mirror of https://github.com/pvnis/srsRAN_4G.git
Merge branch 'working_mac'
commit
1979ca2bcc
@ -1,165 +1,661 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
@ -0,0 +1,52 @@
|
||||
# - Try to find openLTE's liblte
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(PC_OPENLTE QUIET srslte)
|
||||
set(OPENLTE_DEFINITIONS ${PC_OPENLTE_CFLAGS_OTHER})
|
||||
|
||||
FIND_PATH(
|
||||
OPENLTE_LIBLTE_DIRS
|
||||
NAMES liblte_common.h typedefs.h
|
||||
HINTS ${PC_OPENLTE_SRCDIR}/liblte/hdr
|
||||
${PC_OPENLTE_INCLUDEDIR}
|
||||
${PC_OPENLTE_INCLUDE_DIRS}
|
||||
$ENV{OPENLTE_DIR}/liblte/hdr
|
||||
PATHS /usr/local/include
|
||||
/usr/include
|
||||
)
|
||||
|
||||
FIND_PATH(
|
||||
OPENLTE_COMMON_DIRS
|
||||
NAMES typedefs.h
|
||||
HINTS ${PC_OPENLTE_SRCDIR}/cmn_hdr
|
||||
${PC_OPENLTE_INCLUDEDIR}
|
||||
${PC_OPENLTE_INCLUDE_DIRS}
|
||||
$ENV{OPENLTE_DIR}/liblte/hdr
|
||||
PATHS /usr/local/include
|
||||
/usr/include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(
|
||||
OPENLTE_LIBRARIES
|
||||
NAMES lte
|
||||
HINTS ${PC_OPENLTE_BUILDDIR}/liblte
|
||||
${CMAKE_INSTALL_PREFIX}/lib
|
||||
${CMAKE_INSTALL_PREFIX}/lib64
|
||||
$ENV{OPENLTE_DIR}/lib
|
||||
PATHS /usr/local/lib
|
||||
/usr/local/lib64
|
||||
/usr/lib
|
||||
/usr/lib64
|
||||
)
|
||||
|
||||
IF(OPENLTE_LIBLTE_DIRS AND OPENLTE_COMMON_DIRS)
|
||||
SET(OPENLTE_INCLUDE_DIRS ${OPENLTE_LIBLTE_DIRS} ${OPENLTE_COMMON_DIRS})
|
||||
ENDIF(OPENLTE_LIBLTE_DIRS AND OPENLTE_COMMON_DIRS)
|
||||
|
||||
message(STATUS "OPENLTE LIBRARIES " ${OPENLTE_LIBRARIES})
|
||||
message(STATUS "OPENLTE INCLUDE DIRS " ${OPENLTE_INCLUDE_DIRS})
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OPENLTE DEFAULT_MSG OPENLTE_LIBRARIES OPENLTE_INCLUDE_DIRS)
|
||||
MARK_AS_ADVANCED(OPENLTE_LIBRARIES OPENLTE_INCLUDE_DIRS)
|
||||
|
@ -1,42 +0,0 @@
|
||||
#
|
||||
# Copyright 2012-2013 The srsLTE Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution.
|
||||
#
|
||||
# This file is part of the srsLTE library.
|
||||
#
|
||||
# srsLTE is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# srsLTE is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Lesser General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
########################################################################
|
||||
# Install headers
|
||||
########################################################################
|
||||
INSTALL(DIRECTORY include/ DESTINATION "${INCLUDE_DIR}"
|
||||
FILES_MATCHING PATTERN "*.h"
|
||||
PATTERN ".svn" EXCLUDE
|
||||
)
|
||||
|
||||
########################################################################
|
||||
# Add headers to cmake project (useful for IDEs)
|
||||
########################################################################
|
||||
SET(HEADERS_ALL "")
|
||||
FILE(GLOB headers *)
|
||||
FOREACH (_header ${headers})
|
||||
IF(IS_DIRECTORY ${_header})
|
||||
FILE(GLOB_RECURSE tmp "${_header}/*.h")
|
||||
LIST(APPEND HEADERS_ALL ${tmp})
|
||||
ENDIF(IS_DIRECTORY ${_header})
|
||||
ENDFOREACH()
|
||||
ADD_CUSTOM_TARGET (add_common_headers SOURCES ${HEADERS_ALL})
|
||||
|
@ -1,48 +0,0 @@
|
||||
#
|
||||
# Copyright 2012-2013 The srsLTE Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution.
|
||||
#
|
||||
# This file is part of the srsLTE library.
|
||||
#
|
||||
# srsLTE is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# srsLTE is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Lesser General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
########################################################################
|
||||
# Install headers
|
||||
########################################################################
|
||||
INSTALL(DIRECTORY include/
|
||||
DESTINATION "${INCLUDE_DIR}"
|
||||
FILES_MATCHING PATTERN "*.h"
|
||||
PATTERN ".svn" EXCLUDE
|
||||
)
|
||||
|
||||
########################################################################
|
||||
# Add headers to cmake project (useful for IDEs)
|
||||
########################################################################
|
||||
SET(HEADERS_ALL "")
|
||||
FILE(GLOB headers *)
|
||||
FOREACH (_header ${headers})
|
||||
IF(IS_DIRECTORY ${_header})
|
||||
FILE(GLOB_RECURSE tmp "${_header}/*.h")
|
||||
LIST(APPEND HEADERS_ALL ${tmp})
|
||||
ENDIF(IS_DIRECTORY ${_header})
|
||||
ENDFOREACH()
|
||||
ADD_CUSTOM_TARGET (add_cuhd_headers SOURCES ${HEADERS_ALL})
|
||||
|
||||
########################################################################
|
||||
# Add the subdirectories
|
||||
########################################################################
|
||||
ADD_SUBDIRECTORY(lib)
|
||||
|
@ -1,41 +0,0 @@
|
||||
#
|
||||
# Copyright 2012-2013 The srsLTE Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution.
|
||||
#
|
||||
# This file is part of the srsLTE library.
|
||||
#
|
||||
# srsLTE is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# srsLTE is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Lesser General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
FIND_PACKAGE(UHD)
|
||||
|
||||
IF(UHD_FOUND)
|
||||
|
||||
ADD_LIBRARY(cuhd SHARED cuhd_imp.cpp cuhd_utils.c radio_uhd.cc)
|
||||
INCLUDE_DIRECTORIES(${UHD_INCLUDE_DIRS})
|
||||
LINK_DIRECTORIES(${UHD_LIBRARY_DIRS})
|
||||
TARGET_LINK_LIBRARIES(cuhd ${UHD_LIBRARIES})
|
||||
|
||||
LIBLTE_SET_PIC(cuhd)
|
||||
APPEND_INTERNAL_LIST(OPTIONAL_LIBS cuhd)
|
||||
INSTALL(TARGETS cuhd DESTINATION ${LIBRARY_DIR})
|
||||
|
||||
MESSAGE(STATUS " cuhd UHD C wrapper will be installed.")
|
||||
|
||||
ELSE(UHD_FOUND)
|
||||
|
||||
MESSAGE(STATUS " UHD driver not found. CUHD library is not generated")
|
||||
|
||||
ENDIF(UHD_FOUND)
|
@ -1,79 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
#include "srslte/cuhd/cuhd.h"
|
||||
#include "srslte/utils/vector.h"
|
||||
#include "srslte/utils/debug.h"
|
||||
|
||||
int cuhd_rssi_scan(void *uhd, float *freqs, float *rssi, int nof_bands, double fs, int nsamp) {
|
||||
int i, j;
|
||||
int ret = -1;
|
||||
_Complex float *buffer;
|
||||
double f;
|
||||
|
||||
buffer = calloc(nsamp, sizeof(_Complex float));
|
||||
if (!buffer) {
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
cuhd_set_rx_gain(uhd, 20.0);
|
||||
cuhd_set_rx_srate(uhd, fs);
|
||||
|
||||
for (i=0;i<nof_bands;i++) {
|
||||
cuhd_stop_rx_stream(uhd);
|
||||
|
||||
f = (double) freqs[i];
|
||||
cuhd_set_rx_freq(uhd, f);
|
||||
cuhd_rx_wait_lo_locked(uhd);
|
||||
usleep(10000);
|
||||
cuhd_start_rx_stream(uhd);
|
||||
|
||||
/* discard first samples */
|
||||
for (j=0;j<2;j++) {
|
||||
if (cuhd_recv(uhd, buffer, nsamp, 1) != nsamp) {
|
||||
goto free_and_exit;
|
||||
}
|
||||
}
|
||||
rssi[i] = srslte_vec_avg_power_cf(buffer, nsamp);
|
||||
printf("[%3d]: Freq %4.1f Mhz - RSSI: %3.2f dBm\r", i, f/1000000, 10*log10f(rssi[i]) + 30); fflush(stdout);
|
||||
if (SRSLTE_VERBOSE_ISINFO()) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
cuhd_stop_rx_stream(uhd);
|
||||
|
||||
ret = 0;
|
||||
free_and_exit:
|
||||
free(buffer);
|
||||
return ret;
|
||||
}
|
@ -1,12 +1,18 @@
|
||||
function cfo = cfo_estimate_cp(input, Nsyms, sym_len, cp0_len, cp_len)
|
||||
function cfo = cfo_estimate_cp(input_slot, Nsyms, sym_len, cp0_len, cp_len)
|
||||
|
||||
r=zeros(Nsyms, 1);
|
||||
r(1)=sum(input(1:cp0_len).*conj(input(1+sym_len:cp0_len+sym_len)));
|
||||
s=cp0_len+sym_len+1;
|
||||
e=cp0_len+sym_len+cp_len;
|
||||
for i=2:Nsyms
|
||||
r(i)=sum(input(s:e).*conj(input(s+sym_len:e+sym_len)));
|
||||
s=s+sym_len+cp_len;
|
||||
e=e+sym_len+cp_len;
|
||||
% Start correlating from the end. Nsyms is the number of symbols to
|
||||
% correlate starting from the end.
|
||||
|
||||
s=length(input_slot)-sym_len-cp_len;
|
||||
e=length(input_slot)-sym_len;
|
||||
for i=1:Nsyms
|
||||
r(i)=sum(input_slot(s:e).*conj(input_slot(s+sym_len:e+sym_len)));
|
||||
if (i < 7)
|
||||
s=s-sym_len-cp_len;
|
||||
e=e-sym_len-cp_len;
|
||||
else
|
||||
s=s-sym_len-cp0_len;
|
||||
e=e-sym_len-cp0_len;
|
||||
end
|
||||
end
|
||||
cfo=-angle(mean(r))/2/pi;
|
||||
cfo=-angle(mean(r))/pi;
|
@ -1,27 +1,26 @@
|
||||
%clear;
|
||||
M=1000;
|
||||
clear;
|
||||
sym_len=128;
|
||||
x=lte(1:M*15360*sym_len/2048*2000/1536);
|
||||
%x=read_complex('../../../eclipse_osldlib/test.dat');
|
||||
%y=resample(x,99839996,100000000);
|
||||
|
||||
input=resample(x,1536,2000);
|
||||
%input=x;
|
||||
%input=y(1:M*15360*sym_len/2048);
|
||||
%input=resample(x,3840000,1920000);
|
||||
hflen = (sym_len/128)*1920*5;
|
||||
samp_rate = (sym_len/128)*1920000;
|
||||
N_id_2=1;
|
||||
input=read_complex('../../build/lte_signal.dat', hflen*200);
|
||||
|
||||
cp0_len=160*sym_len/2048;
|
||||
cp1_len=144*sym_len/2048;
|
||||
|
||||
slots=reshape(input,15360*sym_len/2048,[]);
|
||||
[n m]=size(slots);
|
||||
%t = (0:length(input)-1).'/samp_rate;
|
||||
%input = input .* exp(-1i*2*pi*2000.0*t);
|
||||
|
||||
subframes=reshape(input,hflen,[]);
|
||||
[n m]=size(subframes);
|
||||
|
||||
cfo=zeros(m,1);
|
||||
output=zeros(size(input));
|
||||
cfdl=struct('NDLRB',6,'CyclicPrefix','Normal','DuplexMode','FDD');
|
||||
cfo=zeros(m,2);
|
||||
for i=1:m
|
||||
cfo(i)=cfo_estimate(slots(:,i),7,sym_len,cp1_len,cp1_len);
|
||||
t=(i-1)*n+1:i*n;
|
||||
%output(t)=input(t).*exp(-1i*2*pi*cfo(i)*t/sym_len);
|
||||
[toffset, cfo(i,2)] = find_pss(subframes(:,i),N_id_2);
|
||||
cfo(i,1) = lteFrequencyOffset(cfdl,subframes(:,i),toffset)/15000;
|
||||
end
|
||||
|
||||
plot(cfo)
|
||||
plot(cfo*15000)
|
||||
legend('Matlab','PSS-based')
|
||||
disp(mean(cfo)*15)
|
||||
|
@ -1,55 +0,0 @@
|
||||
function [ s0_m0 z1_m0 ] = compute_m0( m0)
|
||||
%COMPUTE_S Summary of this function goes here
|
||||
% Detailed explanation goes here
|
||||
|
||||
% Generate s_tilda
|
||||
x_s_tilda(0+1) = 0;
|
||||
x_s_tilda(1+1) = 0;
|
||||
x_s_tilda(2+1) = 0;
|
||||
x_s_tilda(3+1) = 0;
|
||||
x_s_tilda(4+1) = 1;
|
||||
for(i_hat=0:25)
|
||||
x_s_tilda(i_hat+5+1) = mod((x_s_tilda(i_hat+2+1) + x_s_tilda(i_hat+1)), 2);
|
||||
end
|
||||
for(idx=0:30)
|
||||
s_tilda(idx+1) = 1 - 2*x_s_tilda(idx+1);
|
||||
end
|
||||
|
||||
% Generate c_tilda
|
||||
x_c_tilda(0+1) = 0;
|
||||
x_c_tilda(1+1) = 0;
|
||||
x_c_tilda(2+1) = 0;
|
||||
x_c_tilda(3+1) = 0;
|
||||
x_c_tilda(4+1) = 1;
|
||||
for(i_hat=0:25)
|
||||
x_c_tilda(i_hat+5+1) = mod((x_c_tilda(i_hat+3+1) + x_c_tilda(i_hat+1)), 2);
|
||||
end
|
||||
for(idx=0:30)
|
||||
c_tilda(idx+1) = 1 - 2*x_c_tilda(idx+1);
|
||||
end
|
||||
|
||||
% Generate z_tilda
|
||||
x_z_tilda(0+1) = 0;
|
||||
x_z_tilda(1+1) = 0;
|
||||
x_z_tilda(2+1) = 0;
|
||||
x_z_tilda(3+1) = 0;
|
||||
x_z_tilda(4+1) = 1;
|
||||
for(i_hat=0:25)
|
||||
x_z_tilda(i_hat+5+1) = mod((x_z_tilda(i_hat+4+1) + x_z_tilda(i_hat+2+1) + x_z_tilda(i_hat+1+1) + x_z_tilda(i_hat+1)), 2);
|
||||
end
|
||||
for(idx=0:30)
|
||||
z_tilda(idx+1) = 1 - 2*x_z_tilda(idx+1);
|
||||
end
|
||||
|
||||
% Generate s0_m0 and s1_m1
|
||||
for(n=0:30)
|
||||
s0_m0(n+1) = s_tilda(mod(n + m0, 31)+1);
|
||||
end
|
||||
|
||||
% Generate z1_m0 and z1_m1
|
||||
for(n=0:30)
|
||||
z1_m0(n+1) = z_tilda(mod(n + mod(m0, 8), 31)+1);
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1,49 +0,0 @@
|
||||
function [ s1_m1 ] = compute_m1( m1, N_id_2)
|
||||
%COMPUTE_S Summary of this function goes here
|
||||
% Detailed explanation goes here
|
||||
|
||||
% Generate s_tilda
|
||||
x_s_tilda(0+1) = 0;
|
||||
x_s_tilda(1+1) = 0;
|
||||
x_s_tilda(2+1) = 0;
|
||||
x_s_tilda(3+1) = 0;
|
||||
x_s_tilda(4+1) = 1;
|
||||
for(i_hat=0:25)
|
||||
x_s_tilda(i_hat+5+1) = mod((x_s_tilda(i_hat+2+1) + x_s_tilda(i_hat+1)), 2);
|
||||
end
|
||||
for(idx=0:30)
|
||||
s_tilda(idx+1) = 1 - 2*x_s_tilda(idx+1);
|
||||
end
|
||||
|
||||
% Generate c_tilda
|
||||
x_c_tilda(0+1) = 0;
|
||||
x_c_tilda(1+1) = 0;
|
||||
x_c_tilda(2+1) = 0;
|
||||
x_c_tilda(3+1) = 0;
|
||||
x_c_tilda(4+1) = 1;
|
||||
for(i_hat=0:25)
|
||||
x_c_tilda(i_hat+5+1) = mod((x_c_tilda(i_hat+3+1) + x_c_tilda(i_hat+1)), 2);
|
||||
end
|
||||
for(idx=0:30)
|
||||
c_tilda(idx+1) = 1 - 2*x_c_tilda(idx+1);
|
||||
end
|
||||
|
||||
% Generate z_tilda
|
||||
x_z_tilda(0+1) = 0;
|
||||
x_z_tilda(1+1) = 0;
|
||||
x_z_tilda(2+1) = 0;
|
||||
x_z_tilda(3+1) = 0;
|
||||
x_z_tilda(4+1) = 1;
|
||||
for(i_hat=0:25)
|
||||
x_z_tilda(i_hat+5+1) = mod((x_z_tilda(i_hat+4+1) + x_z_tilda(i_hat+2+1) + x_z_tilda(i_hat+1+1) + x_z_tilda(i_hat+1)), 2);
|
||||
end
|
||||
for(idx=0:30)
|
||||
z_tilda(idx+1) = 1 - 2*x_z_tilda(idx+1);
|
||||
end
|
||||
|
||||
% Generate s0_m0 and s1_m1
|
||||
for(n=0:30)
|
||||
s1_m1(n+1) = s_tilda(mod(n + m1, 31)+1);
|
||||
end
|
||||
end
|
||||
|
@ -1,57 +0,0 @@
|
||||
function [out] = convfft(z1,z2)
|
||||
%CONVFFT FFT-based convolution and polynomial multiplication.
|
||||
% C = CONVFFT(A, B) convolves vectors A and B. The resulting
|
||||
% vector is length LENGTH(A)+LENGTH(B)-1.
|
||||
% If A and B are vectors of polynomial coefficients, convolving
|
||||
% them is equivalent to multiplying the two polynomials.
|
||||
%
|
||||
% Please contribute if you find this software useful.
|
||||
% Report bugs to luigi.rosa@tiscali.it
|
||||
%
|
||||
%*****************************************************************
|
||||
% Luigi Rosa
|
||||
% Via Centrale 27
|
||||
% 67042 Civita di Bagno
|
||||
% L'Aquila --- ITALY
|
||||
% email luigi.rosa@tiscali.it
|
||||
% mobile +39 340 3463208
|
||||
% http://utenti.lycos.it/matlab
|
||||
%*****************************************************************
|
||||
%
|
||||
|
||||
|
||||
z1x=size(z1,1);
|
||||
z1y=size(z1,2);
|
||||
z2x=size(z2,1);
|
||||
z2y=size(z2,2);
|
||||
if (~isa(z1,'double'))||(~isa(z2,'double'))||(ndims(z1)>2)||(ndims(z2)>2)
|
||||
disp('Error: input vector must be unidimensional double array');
|
||||
out=[];
|
||||
return;
|
||||
else
|
||||
if ((z1x>1)&&(z1y>1)) || ((z2x>1)&&(z2y>1))
|
||||
out=[];
|
||||
disp('Error: input vectors are double matrices');
|
||||
return;
|
||||
|
||||
else
|
||||
|
||||
if (z1x==1)&&(z1y>1)
|
||||
z1=z1';
|
||||
z1x=z1y;
|
||||
end
|
||||
|
||||
|
||||
if (z2x==1)&&(z2y>1)
|
||||
z2=z2';
|
||||
z2x=z2y;
|
||||
end
|
||||
|
||||
|
||||
if (any(any(imag(z1))))||(any(any(imag(z2))))
|
||||
out=(ifft(fft(z1,z1x+z2x-1).*fft(z2,z1x+z2x-1)));
|
||||
else
|
||||
out=real(ifft(fft(z1,z1x+z2x-1).*fft(z2,z1x+z2x-1)));
|
||||
end
|
||||
end
|
||||
end
|
@ -1,82 +0,0 @@
|
||||
function [coarse_start freq_offset] = find_coarse_time_and_freq_offset(in, N_cp_l_else)
|
||||
|
||||
% Decompose input
|
||||
in_re = real(in);
|
||||
in_im = imag(in);
|
||||
|
||||
abs_corr = zeros(1,960);
|
||||
for(slot=0:10)
|
||||
for(n=1:40:960)
|
||||
corr_re = 0;
|
||||
corr_im = 0;
|
||||
for(z=1:N_cp_l_else)
|
||||
index = (slot*960) + n-1 + z;
|
||||
corr_re = corr_re + in_re(index)*in_re(index+128) + in_im(index)*in_im(index+128);
|
||||
corr_im = corr_im + in_re(index)*in_im(index+128) - in_im(index)*in_re(index+128);
|
||||
end
|
||||
abs_corr(n) = abs_corr(n) + corr_re*corr_re + corr_im*corr_im;
|
||||
end
|
||||
end
|
||||
|
||||
% Find first and second max
|
||||
abs_corr_idx = zeros(1,2);
|
||||
for(m=0:1)
|
||||
abs_corr_max = 0;
|
||||
for(n=1:480)
|
||||
if(abs_corr((m*480)+n) > abs_corr_max)
|
||||
abs_corr_max = abs_corr((m*480)+n);
|
||||
abs_corr_idx(m+1) = (m*480)+n;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% Fine correlation and fraction frequency offset
|
||||
abs_corr = zeros(1,960);
|
||||
corr_freq_err = zeros(1,960);
|
||||
for(slot=1:10)
|
||||
for(idx=1:2)
|
||||
if((abs_corr_idx(idx) - 40) < 1)
|
||||
abs_corr_idx(idx) = 41;
|
||||
end
|
||||
if((abs_corr_idx(idx) + 40) > 960)
|
||||
abs_corr_idx(idx) = 960 - 40;
|
||||
end
|
||||
for(n=abs_corr_idx(idx)-40:abs_corr_idx(idx)+40)
|
||||
corr_re = 0;
|
||||
corr_im = 0;
|
||||
for(z=1:N_cp_l_else)
|
||||
index = (slot*960) + n-1 + z;
|
||||
corr_re = corr_re + in_re(index)*in_re(index+128) + in_im(index)*in_im(index+128);
|
||||
corr_im = corr_im + in_re(index)*in_im(index+128) - in_im(index)*in_re(index+128);
|
||||
end
|
||||
abs_corr(n) = abs_corr(n) + corr_re*corr_re + corr_im*corr_im;
|
||||
corr_freq_err(n) = corr_freq_err(n) + atan2(corr_im, corr_re)/(128*2*pi*(0.0005/960));
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% Find first and second max
|
||||
abs_corr_idx = zeros(1,2);
|
||||
for(m=0:1)
|
||||
abs_corr_max = 0;
|
||||
for(n=1:480)
|
||||
if(abs_corr((m*480)+n) > abs_corr_max)
|
||||
abs_corr_max = abs_corr((m*480)+n);
|
||||
abs_corr_idx(m+1) = (m*480)+n;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% Determine frequency offset FIXME No integer offset is calculated here
|
||||
freq_offset = (corr_freq_err(abs_corr_idx(1))/10 + corr_freq_err(abs_corr_idx(2))/10)/2;23
|
||||
|
||||
% Determine the symbol start locations from the correlation peaks
|
||||
% FIXME Needs some work
|
||||
tmp = abs_corr_idx(1);
|
||||
while(tmp > 0)
|
||||
tmp = tmp - 2192;
|
||||
end
|
||||
for(n=1:7)
|
||||
coarse_start(n) = tmp + (n*2192);
|
||||
end
|
||||
end
|
@ -1,31 +1,18 @@
|
||||
function [ fs eps p_m w2] = find_pss( x, N_id_2, doplot, threshold)
|
||||
if nargin == 2
|
||||
doplot = false;
|
||||
threshold = 0;
|
||||
end
|
||||
if nargin == 3
|
||||
threshold = 0;
|
||||
end
|
||||
function [ fs, cfo, p_m, w2] = find_pss( x, N_id_2)
|
||||
|
||||
c=lte_pss_zc(N_id_2);
|
||||
cc=[zeros(33,1); c; zeros(33,1)];
|
||||
ccf=[0; cc(65:128); cc(2:64)];
|
||||
ccf=conj(ifft(ccf));
|
||||
|
||||
w2=conv(x,ccf);
|
||||
if (doplot)
|
||||
%plot(10*log10(abs(w2)));%./mean(abs(w2))));
|
||||
plot(abs(w2))
|
||||
%axis([0 length(w2) 0 20])
|
||||
end
|
||||
[m i]=max(abs(w2));
|
||||
fs=i-960;
|
||||
p_m = m/mean(abs(w2));
|
||||
|
||||
if doplot
|
||||
fprintf('Frame starts at %d, m=%g, p=%g, p/m=%g dB\n',fs, ...
|
||||
mean(abs(w2)), m, 10*log10(m/mean(abs(w2))));
|
||||
end
|
||||
[m, fs]=max(abs(w2));
|
||||
|
||||
y=ccf.*x(fs-128:fs-1);
|
||||
y0=y(1:64);
|
||||
y1=y(65:length(y));
|
||||
|
||||
cfo=angle(conj(sum(y0))*sum(y1))/pi;
|
||||
p_m = m/mean(abs(w2));
|
||||
|
||||
end
|
||||
|
||||
|
@ -0,0 +1,34 @@
|
||||
#
|
||||
# Copyright 2013-2015 The srsLTE Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution.
|
||||
#
|
||||
# This file is part of the srsLTE library.
|
||||
#
|
||||
# srsLTE is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# srsLTE is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Affero General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
########################################################################
|
||||
# Install headers
|
||||
########################################################################
|
||||
|
||||
remove_definitions(-fvisibility=hidden)
|
||||
|
||||
INCLUDE_DIRECTORIES(radio/include/)
|
||||
INCLUDE_DIRECTORIES(common/include/)
|
||||
|
||||
add_subdirectory(radio)
|
||||
add_subdirectory(common)
|
||||
add_subdirectory(ue)
|
||||
|
@ -0,0 +1,34 @@
|
||||
#
|
||||
# Copyright 2013-2015 The srsLTE Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution.
|
||||
#
|
||||
# This file is part of the srsLTE library.
|
||||
#
|
||||
# srsLTE is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# srsLTE is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Affero General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
INSTALL(DIRECTORY include/
|
||||
DESTINATION "${INCLUDE_DIR}"
|
||||
FILES_MATCHING PATTERN "*.h"
|
||||
PATTERN ".svn" EXCLUDE
|
||||
)
|
||||
|
||||
FILE(GLOB SOURCES "src/*.cc")
|
||||
ADD_LIBRARY(srsapps_common SHARED ${SOURCES})
|
||||
INSTALL(TARGETS srsapps_common DESTINATION ${LIBRARY_DIR})
|
||||
SRSLTE_SET_PIC(srsapps_common)
|
||||
|
||||
FILE(GLOB HEADERS_ALL "include/srsapps/common/*.h")
|
||||
ADD_CUSTOM_TARGET (add_srsapps_common_headers SOURCES ${HEADERS_ALL})
|
@ -0,0 +1,72 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#ifndef BINSEM_H
|
||||
#define BINSEM_H
|
||||
|
||||
/** Implementation of a binary semaphore using POSIX condition variable and mutex
|
||||
*/
|
||||
|
||||
namespace srslte {
|
||||
|
||||
class binsem
|
||||
{
|
||||
public:
|
||||
binsem() {
|
||||
pthread_mutex_init(&mutex, NULL);
|
||||
pthread_cond_init(&cv, NULL);
|
||||
state = true;
|
||||
}
|
||||
~binsem() {
|
||||
pthread_mutex_destroy(&mutex);
|
||||
pthread_cond_destroy(&cv);
|
||||
}
|
||||
void take() {
|
||||
pthread_mutex_lock(&mutex);
|
||||
while(!state) {
|
||||
pthread_cond_wait(&cv, &mutex);
|
||||
}
|
||||
state = false;
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
void give() {
|
||||
pthread_mutex_lock(&mutex);
|
||||
pthread_cond_signal(&cv);
|
||||
state = true;
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
private:
|
||||
pthread_cond_t cv;
|
||||
pthread_mutex_t mutex;
|
||||
bool state;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,64 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
// Generic helper definitions for shared library support
|
||||
#if defined _WIN32 || defined __CYGWIN__
|
||||
#define SRSAPPS_IMPORT __declspec(dllimport)
|
||||
#define SRSAPPS_EXPORT __declspec(dllexport)
|
||||
#define SRSAPPS_LOCAL
|
||||
#else
|
||||
#if __GNUC__ >= 4
|
||||
#define SRSAPPS_IMPORT __attribute__ ((visibility ("default")))
|
||||
#define SRSAPPS_EXPORT __attribute__ ((visibility ("default")))
|
||||
#else
|
||||
#define SRSAPPS_IMPORT
|
||||
#define SRSAPPS_EXPORT
|
||||
#define SRSAPPS_LOCAL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Define SRSAPPS_API
|
||||
// is used for the public API symbols.
|
||||
#ifdef SRSAPPS_DLL_EXPORTS // defined if we are building the SRSAPPS DLL (instead of using it)
|
||||
#define SRSAPPS_EXPORT
|
||||
#else
|
||||
#define SRSAPPS_IMPORT
|
||||
#endif
|
||||
|
||||
|
||||
// Common error codes
|
||||
#define SRSAPPS_SUCCESS 0
|
||||
#define SRSAPPS_ERROR -1
|
||||
#define SRSAPPS_ERROR_INVALID_INPUTS -2
|
||||
|
||||
// cf_t definition
|
||||
typedef _Complex float cf_t;
|
||||
|
||||
#endif // CONFIG_H
|
@ -0,0 +1,99 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
/******************************************************************************
|
||||
* File: log.h
|
||||
*
|
||||
* Description: Abstract logging service
|
||||
*
|
||||
* Reference:
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef LOG_H
|
||||
#define LOG_H
|
||||
|
||||
#define Error(fmt, ...) log_h->error(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define Warning(fmt, ...) log_h->warning(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define Info(fmt, ...) log_h->info(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define Debug(fmt, ...) log_h->debug(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace srslte {
|
||||
|
||||
class log
|
||||
{
|
||||
public:
|
||||
|
||||
log(string service_name_) { service_name = service_name_; tti = 0; level = LOG_LEVEL_NONE; }
|
||||
|
||||
// This function shall be called at the start of every tti for printing tti
|
||||
void step(uint32_t tti_) {
|
||||
tti = tti_;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
LOG_LEVEL_NONE = 0,
|
||||
LOG_LEVEL_INFO,
|
||||
LOG_LEVEL_DEBUG
|
||||
} log_level_t;
|
||||
|
||||
void set_level_info() {
|
||||
level = LOG_LEVEL_INFO;
|
||||
}
|
||||
void set_level_debug() {
|
||||
level = LOG_LEVEL_DEBUG;
|
||||
}
|
||||
|
||||
// Pure virtual methods for logging
|
||||
virtual void error(string message, ...) = 0;
|
||||
virtual void warning(string message, ...) = 0;
|
||||
virtual void info(string message, ...) = 0;
|
||||
virtual void debug(string message, ...) = 0;
|
||||
|
||||
// Same with line and file info
|
||||
virtual void error(string file, int line, string message, ...) = 0;
|
||||
virtual void warning(string file, int line, string message, ...) = 0;
|
||||
virtual void info(string file, int line, string message, ...) = 0;
|
||||
virtual void debug(string file, int line, string message, ...) = 0;
|
||||
|
||||
protected:
|
||||
string get_service_name() { return service_name; }
|
||||
uint32_t tti;
|
||||
log_level_t level;
|
||||
private:
|
||||
string service_name;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -0,0 +1,78 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
#include "srsapps/common/log.h"
|
||||
|
||||
/******************************************************************************
|
||||
* File: log_stout.h
|
||||
*
|
||||
* Description: Logging service through standard output. Inherits log interface
|
||||
*
|
||||
* Reference:
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef LOGSTDOUT_H
|
||||
#define LOGSTDOUT_H
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace srslte {
|
||||
|
||||
class log_stdout : public log
|
||||
{
|
||||
public:
|
||||
|
||||
log_stdout(string service_name_) : log(service_name_) { }
|
||||
|
||||
void error(string message, ...);
|
||||
void warning(string message, ...);
|
||||
void info(string message, ...);
|
||||
void debug(string message, ...);
|
||||
|
||||
// Same with line and file info
|
||||
void error(string file, int line, string message, ...);
|
||||
void warning(string file, int line, string message, ...);
|
||||
void info(string file, int line, string message, ...);
|
||||
void debug(string file, int line, string message, ...);
|
||||
|
||||
private:
|
||||
typedef enum {
|
||||
ERROR=0, WARNING, INFO, DEBUG, NOF_LEVELS
|
||||
} level_t;
|
||||
void printlog(level_t level, uint32_t tti, string file, int line, string message, va_list args);
|
||||
void printlog(level_t level, uint32_t tti, string message, va_list args);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -0,0 +1,93 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#ifndef QBUFF_H
|
||||
#define QBUFF_H
|
||||
|
||||
/** Implementation of a lock-free single-producer single-consumer queue buffer
|
||||
* Communication can be pointer-based or stream based.
|
||||
* Only 1 thread can read and only 1 thread can write.
|
||||
*
|
||||
* Writer:
|
||||
* - Call request, returns a pointer.
|
||||
* - Writes to memory, up to max_msg_size bytes
|
||||
* - Call to push() passing message size
|
||||
* or
|
||||
* - use send()
|
||||
*
|
||||
* Reader:
|
||||
* - Call to pop, receive pointer and message size
|
||||
* - Read memory contents
|
||||
* - Call to release() to release the message buffer
|
||||
* or
|
||||
* - use recv()
|
||||
*/
|
||||
|
||||
namespace srslte {
|
||||
|
||||
class qbuff
|
||||
{
|
||||
public:
|
||||
qbuff();
|
||||
~qbuff();
|
||||
bool init(uint32_t nof_messages, uint32_t max_msg_size);
|
||||
void* request();
|
||||
bool push(uint32_t len);
|
||||
void* pop(uint32_t *len, uint32_t idx);
|
||||
void* pop(uint32_t *len);
|
||||
void* pop();
|
||||
void release();
|
||||
bool isempty();
|
||||
bool isfull();
|
||||
void flush();
|
||||
bool send(void *buffer, uint32_t msg_size);
|
||||
int recv(void* buffer, uint32_t buffer_size);
|
||||
void move_to(qbuff *dst);
|
||||
uint32_t pending_data();
|
||||
private:
|
||||
typedef struct {
|
||||
bool valid;
|
||||
uint32_t len;
|
||||
void *ptr;
|
||||
} pkt_t;
|
||||
|
||||
uint32_t nof_messages;
|
||||
uint32_t max_msg_size;
|
||||
uint32_t rp, wp;
|
||||
|
||||
pkt_t *packets;
|
||||
uint8_t *buffer;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,130 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#ifndef TIMERS_H
|
||||
#define TIMERS_H
|
||||
|
||||
namespace srslte {
|
||||
|
||||
class timer_callback
|
||||
{
|
||||
public:
|
||||
virtual void timer_expired(uint32_t timer_id) = 0;
|
||||
};
|
||||
|
||||
class timers
|
||||
{
|
||||
public:
|
||||
class timer
|
||||
{
|
||||
public:
|
||||
timer() { counter = 0; timeout = 0; running = false; };
|
||||
void set(timer_callback *callback_, uint32_t timeout_) {
|
||||
callback = callback_;
|
||||
timeout = timeout_;
|
||||
}
|
||||
bool is_running() {
|
||||
return counter < timeout;
|
||||
}
|
||||
bool is_expired() {
|
||||
return counter == timeout;
|
||||
}
|
||||
void reset() {
|
||||
counter = 0;
|
||||
}
|
||||
void step() {
|
||||
if (running) {
|
||||
counter++;
|
||||
if (is_expired()) {
|
||||
callback->timer_expired(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
void stop() {
|
||||
running = false;
|
||||
}
|
||||
void run() {
|
||||
running = true;
|
||||
}
|
||||
uint32_t id;
|
||||
private:
|
||||
timer_callback *callback;
|
||||
uint32_t timeout;
|
||||
uint32_t counter;
|
||||
bool running;
|
||||
};
|
||||
|
||||
timers(uint32_t nof_timers_) {
|
||||
nof_timers = nof_timers_;
|
||||
timer_list = new timer[nof_timers];
|
||||
for (uint32_t i=0;i<nof_timers;i++) {
|
||||
timer_list[i].id = i;
|
||||
}
|
||||
}
|
||||
~timers() {
|
||||
delete timer_list;
|
||||
}
|
||||
|
||||
void step_all() {
|
||||
for (int i=0;i<nof_timers;i++) {
|
||||
get(i)->step();
|
||||
}
|
||||
}
|
||||
void stop_all() {
|
||||
for (int i=0;i<nof_timers;i++) {
|
||||
get(i)->stop();
|
||||
}
|
||||
}
|
||||
void run_all() {
|
||||
for (int i=0;i<nof_timers;i++) {
|
||||
get(i)->run();
|
||||
}
|
||||
}
|
||||
void reset_all() {
|
||||
for (int i=0;i<nof_timers;i++) {
|
||||
get(i)->reset();
|
||||
}
|
||||
}
|
||||
timer *get(uint32_t i) {
|
||||
if (i < nof_timers) {
|
||||
return &timer_list[i];
|
||||
} else {
|
||||
printf("Error accessing invalid timer %d (Only %d timers available)\n", i, nof_timers);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
private:
|
||||
uint32_t nof_timers;
|
||||
timer *timer_list;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,137 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "srsapps/common/log_stdout.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace srslte {
|
||||
|
||||
const char* level_str[4] = {"[ERROR ",
|
||||
"[WARN ",
|
||||
"[INFO ",
|
||||
"[DEBUG "};
|
||||
|
||||
void log_stdout::printlog(level_t type, uint32_t tti, string msg, va_list args) {
|
||||
|
||||
printlog(type, tti, string(), -1, msg, args);
|
||||
}
|
||||
|
||||
void log_stdout::printlog(level_t type, uint32_t tti, string file, int line, string msg, va_list args) {
|
||||
|
||||
printf("%s %s",level_str[type], get_service_name().c_str());
|
||||
if (file.length() > 0) {
|
||||
printf("/%-14s", file.substr(file.find_last_of("/")+1,file.find_last_of(".")-1-file.find_last_of("/")).c_str());
|
||||
}
|
||||
if (line >= 0) {
|
||||
printf(" %5d]: ", tti);
|
||||
}
|
||||
vprintf(msg.c_str(), args);
|
||||
}
|
||||
|
||||
void log_stdout::error(string msg, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
printlog(ERROR, tti, msg, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void log_stdout::info(string msg, ...)
|
||||
{
|
||||
if (level >= LOG_LEVEL_INFO) {
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
printlog(INFO, tti, msg, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
void log_stdout::debug(string msg, ...)
|
||||
{
|
||||
if (level >= LOG_LEVEL_DEBUG) {
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
printlog(DEBUG, tti, msg, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
void log_stdout::warning(string msg, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
printlog(WARNING, tti, msg, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
void log_stdout::error(string file, int line, string msg, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
printlog(ERROR, tti, file, line, msg, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void log_stdout::info(string file, int line, string msg, ...)
|
||||
{
|
||||
if (level >= LOG_LEVEL_INFO) {
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
printlog(INFO, tti, file, line, msg, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
void log_stdout::debug(string file, int line, string msg, ...)
|
||||
{
|
||||
if (level >= LOG_LEVEL_DEBUG) {
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
printlog(DEBUG, tti, file, line, msg, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
void log_stdout::warning(string file, int line, string msg, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
printlog(WARNING, tti, file, line, msg, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,213 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#include "srsapps/common/qbuff.h"
|
||||
|
||||
namespace srslte {
|
||||
|
||||
|
||||
qbuff::qbuff()
|
||||
{
|
||||
nof_messages=0;
|
||||
max_msg_size=0;
|
||||
wp = 0;
|
||||
rp = 0;
|
||||
buffer = NULL;
|
||||
packets = NULL;
|
||||
}
|
||||
|
||||
qbuff::~qbuff()
|
||||
{
|
||||
free(buffer);
|
||||
free(packets);
|
||||
}
|
||||
|
||||
bool qbuff::init(uint32_t nof_messages_, uint32_t max_msg_size_)
|
||||
{
|
||||
nof_messages = nof_messages_;
|
||||
max_msg_size = max_msg_size_;
|
||||
|
||||
buffer = (uint8_t*) calloc(nof_messages,max_msg_size);
|
||||
packets = (pkt_t*) calloc(nof_messages,sizeof(pkt_t));
|
||||
if (buffer && packets) {
|
||||
flush();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void qbuff::flush()
|
||||
{
|
||||
wp = 0;
|
||||
rp = 0;
|
||||
for (int i=0;i<nof_messages;i++) {
|
||||
packets[i].valid = false;
|
||||
packets[i].ptr = &buffer[i*max_msg_size];
|
||||
packets[i].len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool qbuff::isempty()
|
||||
{
|
||||
return !packets[rp].valid;
|
||||
}
|
||||
|
||||
bool qbuff::isfull()
|
||||
{
|
||||
return packets[wp].valid;
|
||||
}
|
||||
|
||||
|
||||
void* qbuff::request()
|
||||
{
|
||||
if (!isfull()) {
|
||||
return packets[wp].ptr;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool qbuff::push(uint32_t len)
|
||||
{
|
||||
packets[wp].len = len;
|
||||
packets[wp].valid = true;
|
||||
wp += (wp+1 >= nof_messages)?(1-nof_messages):1;
|
||||
}
|
||||
|
||||
void* qbuff::pop()
|
||||
{
|
||||
return pop(NULL);
|
||||
}
|
||||
|
||||
void* qbuff::pop(uint32_t* len)
|
||||
{
|
||||
if (!isempty()) {
|
||||
if (len) {
|
||||
*len = packets[rp].len;
|
||||
}
|
||||
return packets[rp].ptr;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void* qbuff::pop(uint32_t* len, uint32_t idx)
|
||||
{
|
||||
if (idx == 0) {
|
||||
return pop(len);
|
||||
} else {
|
||||
uint32_t rpp = rp;
|
||||
uint32_t i = 0;
|
||||
while(i<idx && packets[rpp].valid) {
|
||||
rpp += (rpp+1 >= nof_messages)?(1-nof_messages):1;
|
||||
i++;
|
||||
}
|
||||
if (packets[rpp].valid) {
|
||||
if (len) {
|
||||
*len = packets[rpp].len;
|
||||
}
|
||||
return packets[rpp].ptr;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void qbuff::release()
|
||||
{
|
||||
packets[rp].valid = false;
|
||||
packets[rp].len = 0;
|
||||
rp += (rp+1 >= nof_messages)?(1-nof_messages):1;
|
||||
}
|
||||
|
||||
bool qbuff::send(void* buffer, uint32_t msg_size)
|
||||
{
|
||||
if (msg_size <= max_msg_size) {
|
||||
void *ptr = request();
|
||||
if (ptr) {
|
||||
memcpy(ptr, buffer, msg_size);
|
||||
push(msg_size);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t qbuff::pending_data()
|
||||
{
|
||||
uint32_t total_len = 0;
|
||||
for (int i=0;i<nof_messages;i++) {
|
||||
total_len += packets[i].len;
|
||||
}
|
||||
return total_len;
|
||||
}
|
||||
|
||||
// Move packets between queues with only 1 memcpy
|
||||
void qbuff::move_to(qbuff *dst) {
|
||||
uint32_t len;
|
||||
void *ptr_src = pop(&len);
|
||||
if (ptr_src) {
|
||||
void *ptr_dst = dst->request();
|
||||
if (ptr_dst) {
|
||||
memcpy(ptr_dst, ptr_src, len);
|
||||
dst->push(len);
|
||||
release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int qbuff::recv(void* buffer, uint32_t buffer_size)
|
||||
{
|
||||
uint32_t len;
|
||||
void *ptr = pop(&len);
|
||||
if (ptr) {
|
||||
if (len <= buffer_size) {
|
||||
memcpy(buffer, ptr, len);
|
||||
release();
|
||||
return len;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
#
|
||||
# Copyright 2013-2015 The srsLTE Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution.
|
||||
#
|
||||
# This file is part of the srsLTE library.
|
||||
#
|
||||
# srsLTE is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# srsLTE is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Affero General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
FIND_PACKAGE(UHD)
|
||||
|
||||
INSTALL(DIRECTORY include/
|
||||
DESTINATION "${INCLUDE_DIR}"
|
||||
FILES_MATCHING PATTERN "*.h"
|
||||
PATTERN ".svn" EXCLUDE
|
||||
)
|
||||
|
||||
IF(UHD_FOUND)
|
||||
FILE(GLOB SOURCES "src/*.cc")
|
||||
ADD_LIBRARY(srsapps_radio SHARED ${SOURCES})
|
||||
INSTALL(TARGETS srsapps_radio DESTINATION ${LIBRARY_DIR})
|
||||
SRSLTE_SET_PIC(srsapps_radio)
|
||||
ENDIF(UHD_FOUND)
|
||||
|
||||
FILE(GLOB HEADERS_ALL "include/srsapps/radio/*.h")
|
||||
ADD_CUSTOM_TARGET (add_srsapps_radio_headers SOURCES ${HEADERS_ALL})
|
@ -0,0 +1,27 @@
|
||||
#
|
||||
# Copyright 2013-2015 The srsLTE Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution.
|
||||
#
|
||||
# This file is part of the srsLTE library.
|
||||
#
|
||||
# srsLTE is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# srsLTE is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Affero General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
INCLUDE_DIRECTORIES(phy/include/)
|
||||
INCLUDE_DIRECTORIES(mac/include/)
|
||||
|
||||
add_subdirectory(phy)
|
||||
add_subdirectory(mac)
|
||||
|
@ -0,0 +1,36 @@
|
||||
#
|
||||
# Copyright 2013-2015 The srsLTE Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution.
|
||||
#
|
||||
# This file is part of the srsLTE library.
|
||||
#
|
||||
# srsLTE is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# srsLTE is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Affero General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
INSTALL(DIRECTORY include/
|
||||
DESTINATION "${INCLUDE_DIR}"
|
||||
FILES_MATCHING PATTERN "*.h"
|
||||
PATTERN ".svn" EXCLUDE
|
||||
)
|
||||
|
||||
FILE(GLOB SOURCES "src/*.cc")
|
||||
ADD_LIBRARY(srsapps_ue_mac SHARED ${SOURCES})
|
||||
INSTALL(TARGETS srsapps_ue_mac DESTINATION ${LIBRARY_DIR})
|
||||
SRSLTE_SET_PIC(srsapps_ue_mac)
|
||||
|
||||
FILE(GLOB HEADERS_ALL "include/srsapps/ue/mac/*.h")
|
||||
ADD_CUSTOM_TARGET (add_ue_mac_headers SOURCES ${HEADERS_ALL})
|
||||
|
||||
ADD_SUBDIRECTORY(test)
|
@ -0,0 +1,87 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "srsapps/ue/phy/phy.h"
|
||||
#include "srsapps/common/log.h"
|
||||
#include "srsapps/ue/mac/mac_io.h"
|
||||
#include "srsapps/common/timers.h"
|
||||
#include "srsapps/ue/mac/mac_params.h"
|
||||
#include "srsapps/ue/mac/pdu.h"
|
||||
#include "srsapps/ue/mac/sdu_handler.h"
|
||||
|
||||
#ifndef DEMUX_H
|
||||
#define DEMUX_H
|
||||
|
||||
/* Logical Channel Demultiplexing and MAC CE dissassemble */
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
class demux
|
||||
{
|
||||
public:
|
||||
demux();
|
||||
void init(phy* phy_h_, log* log_h_, mac_io* mac_io_h_, timers* timers_db_);
|
||||
|
||||
void add_sdu_handler(sdu_handler *handler);
|
||||
|
||||
void push_pdu(uint8_t *mac_pdu, uint32_t nof_bits);
|
||||
void push_pdu_bcch(uint8_t *mac_pdu, uint32_t nof_bits);
|
||||
void push_pdu_temp_crnti(uint8_t *mac_pdu, uint32_t nof_bits);
|
||||
bool is_temp_crnti_pending();
|
||||
bool is_contention_resolution_id_pending();
|
||||
void demultiplex_pending_pdu();
|
||||
void discard_pending_pdu();
|
||||
|
||||
uint64_t get_contention_resolution_id();
|
||||
|
||||
private:
|
||||
sch_pdu mac_msg;
|
||||
sch_pdu pending_mac_msg;
|
||||
|
||||
void process_pdu(sch_pdu *pdu);
|
||||
bool process_ce(sch_subh *subheader);
|
||||
|
||||
uint64_t contention_resolution_id;
|
||||
bool pending_temp_rnti;
|
||||
bool has_pending_contention_resolution_id;
|
||||
|
||||
phy *phy_h;
|
||||
log *log_h;
|
||||
mac_io *mac_io_h;
|
||||
timers *timers_db;
|
||||
sdu_handler *sdu_handler_;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -0,0 +1,101 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include "srsapps/common/log.h"
|
||||
#include "srsapps/ue/phy/phy.h"
|
||||
#include "srsapps/ue/mac/mac_params.h"
|
||||
#include "srsapps/common/timers.h"
|
||||
#include "srsapps/ue/mac/demux.h"
|
||||
|
||||
#ifndef DLHARQ_H
|
||||
#define DLHARQ_H
|
||||
|
||||
/* Downlink HARQ entity as defined in 5.3.2 of 36.321 */
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
typedef _Complex float cf_t;
|
||||
|
||||
class dl_harq_entity
|
||||
{
|
||||
public:
|
||||
|
||||
const static uint32_t NOF_HARQ_PROC = 8;
|
||||
const static uint32_t HARQ_BCCH_PID = NOF_HARQ_PROC;
|
||||
|
||||
dl_harq_entity();
|
||||
bool init(srslte_cell_t cell, uint32_t max_payload_len, srslte::log *log_h_, timers *timers_, demux *demux_unit);
|
||||
bool is_sps(uint32_t pid);
|
||||
void set_harq_info(uint32_t pid, dl_sched_grant *grant);
|
||||
void receive_data(uint32_t tti, uint32_t pid, dl_buffer *dl_buffer, phy *phy_h);
|
||||
void reset();
|
||||
bool is_ack_pending_resolution();
|
||||
void send_pending_ack_contention_resolution();
|
||||
private:
|
||||
|
||||
|
||||
class dl_harq_process {
|
||||
public:
|
||||
dl_harq_process();
|
||||
bool init(srslte_cell_t cell, uint32_t max_payload_len, dl_harq_entity *parent);
|
||||
void set_harq_info(dl_sched_grant *grant);
|
||||
void receive_data(uint32_t tti, dl_buffer *dl_buffer, phy *phy_h);
|
||||
void reset();
|
||||
// Called after the contention resolution is terminated to send pending ACKs, if any
|
||||
void send_pending_ack_contention_resolution();
|
||||
uint32_t pid;
|
||||
private:
|
||||
|
||||
bool is_initiated;
|
||||
dl_harq_entity *harq_entity;
|
||||
uint8_t *payload;
|
||||
uint32_t max_payload_len;
|
||||
dl_sched_grant cur_grant;
|
||||
dl_sched_grant pending_ack_grant;
|
||||
ul_buffer *pending_ul_buffer;
|
||||
bool is_first_tx;
|
||||
bool is_first_decoded;
|
||||
bool pending_ack;
|
||||
srslte::log *log_h;
|
||||
|
||||
srslte_softbuffer_rx_t softbuffer;
|
||||
};
|
||||
|
||||
dl_harq_process proc[NOF_HARQ_PROC+1];
|
||||
timers *timers_db;
|
||||
demux *demux_unit;
|
||||
srslte::log *log_h;
|
||||
int pending_ack_pid;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,59 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include "srsapps/common/log.h"
|
||||
#include "srsapps/ue/phy/phy.h"
|
||||
#include "srsapps/ue/mac/mac_params.h"
|
||||
#include "srsapps/common/timers.h"
|
||||
|
||||
#ifndef DLSPS_H
|
||||
#define DLSPS_H
|
||||
|
||||
/* Downlink Semi-Persistent schedulign (Section 5.10.1) */
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
typedef _Complex float cf_t;
|
||||
|
||||
class dl_sps
|
||||
{
|
||||
public:
|
||||
|
||||
void clear();
|
||||
void reset(uint32_t tti, dl_sched_grant *grant);
|
||||
dl_sched_grant *get_pending_grant(uint32_t tti);
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,150 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include "srsapps/common/log.h"
|
||||
#include "srsapps/common/tti_sync.h"
|
||||
#include "srsapps/ue/phy/phy.h"
|
||||
#include "srsapps/ue/mac/mac_params.h"
|
||||
#include "srsapps/ue/mac/dl_harq.h"
|
||||
#include "srsapps/ue/mac/ul_harq.h"
|
||||
#include "srsapps/ue/mac/dl_sps.h"
|
||||
#include "srsapps/ue/mac/ul_sps.h"
|
||||
#include "srsapps/common/timers.h"
|
||||
#include "srsapps/ue/mac/mac_io.h"
|
||||
#include "srsapps/ue/mac/proc_ra.h"
|
||||
#include "srsapps/ue/mac/proc_sr.h"
|
||||
#include "srsapps/ue/mac/proc_bsr.h"
|
||||
#include "srsapps/ue/mac/proc_phr.h"
|
||||
#include "srsapps/ue/mac/mux.h"
|
||||
#include "srsapps/ue/mac/demux.h"
|
||||
#include "srsapps/ue/mac/sdu_handler.h"
|
||||
|
||||
#ifndef UEMAC_H
|
||||
#define UEMAC_H
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
typedef _Complex float cf_t;
|
||||
|
||||
class mac : public timer_callback
|
||||
{
|
||||
public:
|
||||
mac() : timers_db((uint32_t) NOF_MAC_TIMERS) {}
|
||||
bool init(phy *phy_h, tti_sync *ttisync, log *log_h);
|
||||
void stop();
|
||||
int get_tti();
|
||||
void main_radio_loop(); // called after thread creation
|
||||
|
||||
void add_sdu_handler(sdu_handler *handler);
|
||||
|
||||
bool send_sdu(uint32_t lcid, uint8_t *sdu_payload, uint32_t nbytes);
|
||||
bool send_ccch_sdu(uint8_t *sdu_payload, uint32_t nbytes);
|
||||
bool send_dtch0_sdu(uint8_t *sdu_payload, uint32_t nbytes); // SRB0
|
||||
bool send_dcch0_sdu(uint8_t *sdu_payload, uint32_t nbytes); // DRB0
|
||||
|
||||
int recv_sdu(uint32_t lcid, uint8_t *sdu_payload, uint32_t nbytes);
|
||||
int recv_bcch_sdu(uint8_t *sdu_payload, uint32_t buffer_len_nbytes);
|
||||
int recv_ccch_sdu(uint8_t *sdu_payload, uint32_t buffer_len_nbytes);
|
||||
int recv_dtch0_sdu(uint8_t *sdu_payload, uint32_t buffer_len_nbytes); // SRB0
|
||||
int recv_dcch0_sdu(uint8_t *sdu_payload, uint32_t buffer_len_nbytes); // DRB0
|
||||
|
||||
void setup_lcid(uint32_t lcid, uint32_t lcg, uint32_t priority, int PBR_x_tti, uint32_t BSD);
|
||||
|
||||
void set_param(mac_params::mac_param_t param, int64_t value);
|
||||
|
||||
void reconfiguration();
|
||||
void reset();
|
||||
|
||||
void timer_expired(uint32_t timer_id);
|
||||
|
||||
enum {
|
||||
HARQ_RTT = 0,
|
||||
TIME_ALIGNMENT,
|
||||
CONTENTION_TIMER,
|
||||
BSR_TIMER_PERIODIC,
|
||||
BSR_TIMER_RETX,
|
||||
NOF_MAC_TIMERS
|
||||
} mac_timers_t;
|
||||
|
||||
private:
|
||||
// Interaction with PHY
|
||||
tti_sync *ttisync;
|
||||
phy *phy_h;
|
||||
|
||||
log *log_h;
|
||||
|
||||
/* Logical channel (lch) IO */
|
||||
mac_io mac_io_lch;
|
||||
|
||||
|
||||
mac_params params_db;
|
||||
pthread_t mac_thread;
|
||||
static void* mac_thread_fnc(void*);
|
||||
|
||||
int tti;
|
||||
bool started = false;
|
||||
bool is_synchronized;
|
||||
bool is_first_temporal;
|
||||
|
||||
/* Multiplexing/Demultiplexing Units */
|
||||
mux mux_unit;
|
||||
demux demux_unit;
|
||||
|
||||
/* DL/UL HARQ */
|
||||
dl_harq_entity dl_harq;
|
||||
ul_harq_entity ul_harq;
|
||||
|
||||
/* DL/UL Semi-Persistent Sched */
|
||||
dl_sps dl_sps_assig;
|
||||
ul_sps ul_sps_assig;
|
||||
uint32_t get_harq_sps_pid(uint32_t tti);
|
||||
|
||||
/* MAC Uplink-related Procedures */
|
||||
ra_proc ra_procedure;
|
||||
sr_proc sr_procedure;
|
||||
bsr_proc bsr_procedure;
|
||||
phr_proc phr_procedure;
|
||||
|
||||
/* Other procedures */
|
||||
void process_dl_grants(uint32_t tti);
|
||||
bool process_ul_grants(uint32_t tti);
|
||||
void receive_pch(uint32_t tti);
|
||||
|
||||
/* Functions for MAC Timers */
|
||||
timers timers_db;
|
||||
void setup_timers();
|
||||
void timeAlignmentTimerExpire();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,112 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include "srsapps/common/qbuff.h"
|
||||
|
||||
#ifndef MACIO_H
|
||||
#define MACIO_H
|
||||
|
||||
/* Manages all MAC buffers including:
|
||||
* - communication with higher layers through logical channels
|
||||
* - communication between logical channels buffers and Dissassembly/Assembly unit
|
||||
* - communication between Dissassembly/Assembly unit and Msg3 buffer
|
||||
*
|
||||
* For logical channels, IN means higher layers to MAC. OUT means MAC to higher layers.
|
||||
*
|
||||
* See queue.h for instructions on how to manage buffers
|
||||
*/
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
class mac_io
|
||||
{
|
||||
public:
|
||||
|
||||
// list of logical channels
|
||||
// Keep this order to match LoCH id with RB
|
||||
typedef enum {
|
||||
// Downlink (UE MAC -> UE RRC)
|
||||
MAC_LCH_CCCH_DL = 0, // SRB0
|
||||
MAC_LCH_DCCH0_DL, // SRB1
|
||||
MAC_LCH_DCCH1_DL, // SRB2
|
||||
MAC_LCH_DTCH0_DL, // DRB0
|
||||
MAC_LCH_DTCH1_DL, // DRB1
|
||||
MAC_LCH_DTCH2_DL, // DRB2
|
||||
MAC_LCH_BCCH_DL, // N/A
|
||||
MAC_LCH_PCCH_DL, // N/A
|
||||
|
||||
// Uplink (UE RLC -> UE MAC)
|
||||
MAC_LCH_CCCH_UL, // SRB0
|
||||
MAC_LCH_DCCH0_UL, // SRB1
|
||||
MAC_LCH_DCCH1_UL, // SRB2
|
||||
MAC_LCH_DTCH0_UL, // DRB0
|
||||
MAC_LCH_DTCH1_UL, // DRB1
|
||||
MAC_LCH_DTCH2_UL, // DRB2
|
||||
|
||||
MAC_NOF_QUEUES
|
||||
} mac_lch_t;
|
||||
|
||||
const static int NOF_DL_LCH = MAC_LCH_PCCH_DL - MAC_LCH_CCCH_DL;
|
||||
const static int NOF_UL_LCH = MAC_LCH_DTCH2_UL - MAC_LCH_CCCH_UL;
|
||||
|
||||
const static int DEFAULT_MSG_SZ = 8*1024; // 8 Kbytes
|
||||
const static int DEFAULT_NOF_MESSAGES = 8;
|
||||
|
||||
|
||||
qbuff* get(mac_lch_t ch) {
|
||||
return get((uint32_t) ch);
|
||||
}
|
||||
|
||||
qbuff* get(int32_t lchid) {
|
||||
if (lchid < MAC_NOF_QUEUES) {
|
||||
return &queues[lchid];
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Move packets between queues with only 1 memcpy
|
||||
void move(mac_lch_t src, mac_lch_t dst) {
|
||||
get(src)->move_to(get(dst));
|
||||
}
|
||||
|
||||
mac_io() {
|
||||
for (int i=0;i<MAC_NOF_QUEUES;i++) {
|
||||
queues[i].init(DEFAULT_NOF_MESSAGES, DEFAULT_MSG_SZ);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
qbuff queues[MAC_NOF_QUEUES];
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,103 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "srslte/srslte.h"
|
||||
#include "srsapps/common/params_db.h"
|
||||
|
||||
#ifndef MACPARAMS_H
|
||||
#define MACPARAMS_H
|
||||
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
class mac_params : public params_db
|
||||
{
|
||||
public:
|
||||
|
||||
mac_params() : params_db(NOF_PARAMS) {}
|
||||
~mac_params() {}
|
||||
|
||||
typedef enum {
|
||||
|
||||
// These 4 parameters must be together!!
|
||||
RNTI_C = 0,
|
||||
RNTI_SPS,
|
||||
RNTI_TEMP,
|
||||
RNTI_RA,
|
||||
|
||||
SPS_DL_SCHED_INTERVAL,
|
||||
SPS_DL_NOF_PROC,
|
||||
|
||||
BCCH_SI_WINDOW_ST,
|
||||
BCCH_SI_WINDOW_LEN,
|
||||
|
||||
PCCH_RECEIVE,
|
||||
|
||||
CONTENTION_ID, // Transmitted UE Contention ID
|
||||
|
||||
TIMER_TIMEALIGN,
|
||||
|
||||
// Random Access parameters. See 5.1.1
|
||||
RA_CONFIGINDEX,
|
||||
RA_PREAMBLEINDEX,
|
||||
RA_MASKINDEX,
|
||||
RA_NOFPREAMBLES,
|
||||
RA_NOFGROUPAPREAMBLES,
|
||||
RA_MESSAGEPOWEROFFSETB,
|
||||
RA_MESSAGESIZEA,
|
||||
RA_PCMAX,
|
||||
RA_DELTAPREAMBLEMSG3,
|
||||
RA_RESPONSEWINDOW,
|
||||
RA_POWERRAMPINGSTEP,
|
||||
RA_PREAMBLETRANSMAX,
|
||||
RA_INITRECEIVEDPOWER,
|
||||
RA_CONTENTIONTIMER,
|
||||
|
||||
SR_PUCCH_CONFIGURED,
|
||||
SR_TRANS_MAX,
|
||||
|
||||
BSR_TIMER_PERIODIC,
|
||||
BSR_TIMER_RETX,
|
||||
|
||||
HARQ_MAXTX,
|
||||
HARQ_MAXMSG3TX,
|
||||
|
||||
PDSCH_RSPOWER,
|
||||
PDSCH_PB,
|
||||
|
||||
|
||||
NOF_PARAMS,
|
||||
} mac_param_t;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,105 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "srsapps/common/log.h"
|
||||
#include "srsapps/ue/mac/mac_io.h"
|
||||
#include "srsapps/ue/mac/mac_params.h"
|
||||
#include "srsapps/ue/mac/pdu.h"
|
||||
#include "srsapps/ue/mac/proc_bsr.h"
|
||||
|
||||
#ifndef MUX_H
|
||||
#define MUX_H
|
||||
|
||||
/* Logical Channel Multiplexing and Prioritization + Msg3 Buffer */
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
class mux
|
||||
{
|
||||
public:
|
||||
mux();
|
||||
void reset();
|
||||
void init(log *log_h, mac_io *mac_io_h, bsr_proc *bsr_procedure);
|
||||
|
||||
bool is_pending_ccch_sdu();
|
||||
bool is_pending_any_sdu();
|
||||
bool is_pending_sdu(uint32_t lcid);
|
||||
|
||||
uint8_t* pdu_pop(uint32_t pdu_sz);
|
||||
bool pdu_move_to_msg3(uint32_t pdu_sz);
|
||||
void pdu_release();
|
||||
|
||||
uint8_t* msg3_pop(uint32_t pdu_sz);
|
||||
void msg3_flush();
|
||||
void msg3_transmitted();
|
||||
bool msg3_is_transmitted();
|
||||
|
||||
void append_crnti_ce_next_tx(uint16_t crnti);
|
||||
|
||||
void set_priority(uint32_t lcid, uint32_t priority, int PBR_x_tti, uint32_t BSD);
|
||||
|
||||
private:
|
||||
bool assemble_pdu(uint32_t pdu_sz);
|
||||
bool allocate_sdu(uint32_t lcid, sch_pdu *pdu);
|
||||
bool allocate_sdu(uint32_t lcid, sch_pdu *pdu, uint32_t *sdu_sz);
|
||||
|
||||
int64_t Bj[mac_io::NOF_UL_LCH];
|
||||
int PBR[mac_io::NOF_UL_LCH]; // -1 sets to infinity
|
||||
uint32_t BSD[mac_io::NOF_UL_LCH];
|
||||
uint32_t priority[mac_io::NOF_UL_LCH];
|
||||
uint32_t priority_sorted[mac_io::NOF_UL_LCH];
|
||||
uint32_t lchid_sorted[mac_io::NOF_UL_LCH];
|
||||
uint32_t nof_tx_pkts[mac_io::NOF_UL_LCH];
|
||||
|
||||
// Mutex for priority setting from outside MAC
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
log *log_h;
|
||||
mac_io *mac_io_h;
|
||||
bsr_proc *bsr_procedure;
|
||||
uint16_t pending_crnti_ce;
|
||||
|
||||
/* Msg3 Buffer */
|
||||
static const uint32_t MSG3_BUFF_SZ = 128;
|
||||
qbuff msg3_buff;
|
||||
|
||||
/* PDU Buffer */
|
||||
static const uint32_t PDU_BUFF_SZ = 16*1024;
|
||||
qbuff pdu_buff;
|
||||
sch_pdu pdu_msg;
|
||||
bool msg3_has_been_transmitted;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -0,0 +1,293 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include "srsapps/common/log.h"
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#ifndef MACPDU_H
|
||||
#define MACPDU_H
|
||||
|
||||
/* MAC PDU Packing/Unpacking functions. Section 6 of 36.321 */
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
|
||||
template<class SubH>
|
||||
class pdu
|
||||
{
|
||||
public:
|
||||
|
||||
pdu(uint32_t max_subheaders_) : subheaders(max_subheaders_) {
|
||||
max_subheaders = max_subheaders_;
|
||||
nof_subheaders = 0;
|
||||
cur_idx = -1;
|
||||
pdu_len = 0;
|
||||
rem_len = 0;
|
||||
for (int i=0;i<max_subheaders;i++) {
|
||||
subheaders[i].parent = this;
|
||||
}
|
||||
}
|
||||
|
||||
void fprint(FILE *stream) {
|
||||
fprintf(stream, "Number of Subheaders: %d\n", nof_subheaders);
|
||||
for (int i=0;i<nof_subheaders;i++) {
|
||||
fprintf(stream, " -- Subheader %d: ", i);
|
||||
subheaders[i].fprint(stream);
|
||||
}
|
||||
}
|
||||
|
||||
/* Resets the Read/Write position and remaining PDU length */
|
||||
void reset() {
|
||||
cur_idx = -1;
|
||||
rem_len = pdu_len;
|
||||
}
|
||||
|
||||
/* Prepares the PDU for parsing or writing by setting the number of subheaders to 0 and the pdu length */
|
||||
void init(uint32_t pdu_len_bytes) {
|
||||
init(pdu_len_bytes, false);
|
||||
}
|
||||
void init(uint32_t pdu_len_bytes, bool is_ulsch) {
|
||||
nof_subheaders = 0;
|
||||
pdu_len = pdu_len_bytes;
|
||||
rem_len = pdu_len;
|
||||
pdu_is_ul = is_ulsch;
|
||||
reset();
|
||||
for (int i=0;i<max_subheaders;i++) {
|
||||
subheaders[i].init();
|
||||
}
|
||||
}
|
||||
|
||||
bool new_subh() {
|
||||
if (nof_subheaders < max_subheaders - 1) {
|
||||
nof_subheaders++;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool next() {
|
||||
if (cur_idx < nof_subheaders - 1) {
|
||||
cur_idx++;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SubH* get() {
|
||||
if (cur_idx >= 0) {
|
||||
return &subheaders[cur_idx];
|
||||
}
|
||||
}
|
||||
|
||||
// Section 6.1.2
|
||||
void parse_packet(uint8_t *ptr) {
|
||||
uint8_t *init_ptr = ptr;
|
||||
nof_subheaders = 0;
|
||||
while(subheaders[nof_subheaders].read_subheader(&ptr)) {
|
||||
nof_subheaders++;
|
||||
}
|
||||
nof_subheaders++;
|
||||
for (int i=0;i<nof_subheaders;i++) {
|
||||
subheaders[i].read_payload(&ptr);
|
||||
}
|
||||
}
|
||||
bool is_ul() {
|
||||
return pdu_is_ul;
|
||||
}
|
||||
|
||||
virtual bool write_packet(uint8_t *ptr) = 0;
|
||||
|
||||
protected:
|
||||
std::vector<SubH> subheaders;
|
||||
uint32_t pdu_len;
|
||||
uint32_t rem_len;
|
||||
int cur_idx;
|
||||
int nof_subheaders;
|
||||
uint32_t max_subheaders;
|
||||
bool pdu_is_ul;
|
||||
};
|
||||
|
||||
template<class SubH>
|
||||
class subh
|
||||
{
|
||||
public:
|
||||
|
||||
virtual bool read_subheader(uint8_t** ptr) = 0;
|
||||
virtual void read_payload(uint8_t **ptr) = 0;
|
||||
virtual void write_subheader(uint8_t** ptr, bool is_last) = 0;
|
||||
virtual void write_payload(uint8_t **ptr) = 0;
|
||||
virtual void fprint(FILE *stream) = 0;
|
||||
|
||||
pdu<SubH>* parent;
|
||||
|
||||
private:
|
||||
virtual void init() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class sch_subh : public subh<sch_subh>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
typedef enum {
|
||||
PHD_REPORT = 26,
|
||||
C_RNTI = 27,
|
||||
CON_RES_ID = 28,
|
||||
TRUNC_BSR = 28,
|
||||
TA_CMD = 29,
|
||||
SHORT_BSR = 29,
|
||||
DRX_CMD = 30,
|
||||
LONG_BSR = 30,
|
||||
PADDING = 31,
|
||||
SDU = 0
|
||||
} cetype;
|
||||
|
||||
// Reading functions
|
||||
bool is_sdu();
|
||||
cetype ce_type();
|
||||
uint32_t size_plus_header();
|
||||
void set_payload_size(uint32_t size);
|
||||
|
||||
bool read_subheader(uint8_t** ptr);
|
||||
void read_payload(uint8_t **ptr);
|
||||
uint32_t get_sdu_lcid();
|
||||
uint32_t get_sdu_nbytes();
|
||||
uint8_t* get_sdu_ptr();
|
||||
|
||||
uint16_t get_c_rnti();
|
||||
uint64_t get_con_res_id();
|
||||
uint8_t get_ta_cmd();
|
||||
uint8_t get_phd();
|
||||
|
||||
// Writing functions
|
||||
void write_subheader(uint8_t** ptr, bool is_last);
|
||||
void write_payload(uint8_t **ptr);
|
||||
bool set_sdu(uint32_t lcid, uint8_t *ptr, uint32_t nof_bytes);
|
||||
bool set_c_rnti(uint16_t crnti);
|
||||
bool set_bsr(uint32_t buff_size[4], sch_subh::cetype format);
|
||||
bool set_con_res_id(uint64_t con_res_id);
|
||||
bool set_ta_cmd(uint8_t ta_cmd);
|
||||
bool set_phd(uint8_t phd);
|
||||
void set_padding();
|
||||
|
||||
void init();
|
||||
void fprint(FILE *stream);
|
||||
|
||||
private:
|
||||
static const int MAX_CE_PAYLOAD_LEN = 8;
|
||||
uint32_t lcid;
|
||||
uint32_t nof_bytes;
|
||||
uint8_t* sdu_payload_ptr;
|
||||
bool F_bit;
|
||||
uint8_t ce_payload[MAX_CE_PAYLOAD_LEN*8];
|
||||
uint32_t sizeof_ce(uint32_t lcid, bool is_ul);
|
||||
uint8_t buff_size_table(uint32_t buffer_size);
|
||||
};
|
||||
|
||||
class sch_pdu : public pdu<sch_subh>
|
||||
{
|
||||
public:
|
||||
|
||||
sch_pdu(uint32_t max_rars) : pdu(max_rars) {}
|
||||
|
||||
void parse_packet(uint8_t *ptr);
|
||||
bool write_packet(uint8_t *ptr);
|
||||
bool has_space_ce(uint32_t nbytes);
|
||||
bool has_space_sdu(uint32_t nbytes);
|
||||
uint32_t size();
|
||||
uint32_t rem_size();
|
||||
static uint32_t size_plus_header_sdu(uint32_t nbytes);
|
||||
bool update_space_ce(uint32_t nbytes);
|
||||
bool update_space_sdu(uint32_t nbytes);
|
||||
void fprint(FILE *stream);
|
||||
|
||||
};
|
||||
|
||||
class rar_subh : public subh<rar_subh>
|
||||
{
|
||||
public:
|
||||
|
||||
static const uint32_t RAR_GRANT_LEN = 20;
|
||||
|
||||
// Reading functions
|
||||
bool read_subheader(uint8_t** ptr);
|
||||
void read_payload(uint8_t** ptr);
|
||||
uint32_t get_rapid();
|
||||
uint32_t get_ta_cmd();
|
||||
uint16_t get_temp_crnti();
|
||||
void get_sched_grant(uint8_t grant[RAR_GRANT_LEN]);
|
||||
|
||||
// Writing functoins
|
||||
void write_subheader(uint8_t** ptr, bool is_last);
|
||||
void write_payload(uint8_t** ptr);
|
||||
void set_rapid(uint32_t rapid);
|
||||
void set_ta_cmd(uint32_t ta);
|
||||
void set_temp_crnti(uint16_t temp_rnti);
|
||||
void set_sched_grant(uint8_t grant[RAR_GRANT_LEN]);
|
||||
|
||||
void init();
|
||||
void fprint(FILE *stream);
|
||||
|
||||
private:
|
||||
uint8_t grant[RAR_GRANT_LEN];
|
||||
uint32_t ta;
|
||||
uint16_t temp_rnti;
|
||||
uint32_t preamble;
|
||||
};
|
||||
|
||||
class rar_pdu : public pdu<rar_subh>
|
||||
{
|
||||
public:
|
||||
|
||||
rar_pdu(uint32_t max_rars);
|
||||
|
||||
void set_backoff(uint8_t bi);
|
||||
bool has_backoff();
|
||||
uint8_t get_backoff();
|
||||
|
||||
bool write_packet(uint8_t* ptr);
|
||||
void fprint(FILE *stream);
|
||||
|
||||
private:
|
||||
bool has_backoff_indicator;
|
||||
uint8_t backoff_indicator;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -0,0 +1,62 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef PROC_H
|
||||
#define PROC_H
|
||||
|
||||
/* Interface for a MAC procedure */
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
class proc
|
||||
{
|
||||
public:
|
||||
proc() {
|
||||
running = false;
|
||||
}
|
||||
void run() {
|
||||
running = true;
|
||||
}
|
||||
void stop() {
|
||||
running = false;
|
||||
}
|
||||
bool is_running() {
|
||||
return running;
|
||||
}
|
||||
virtual void step(uint32_t tti) = 0;
|
||||
private:
|
||||
bool running;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,97 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "srsapps/common/log.h"
|
||||
#include "srsapps/ue/mac/proc.h"
|
||||
#include "srsapps/ue/mac/mac_params.h"
|
||||
#include "srsapps/ue/mac/mac_io.h"
|
||||
#include "srsapps/common/timers.h"
|
||||
|
||||
#ifndef PROCBSR_H
|
||||
#define PROCBSR_H
|
||||
|
||||
/* Buffer status report procedure */
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
class bsr_proc : public proc, timer_callback
|
||||
{
|
||||
public:
|
||||
bsr_proc();
|
||||
void init(log *log_h, timers *timers_db, mac_params *params_db, mac_io *mac_io_h);
|
||||
void step(uint32_t tti);
|
||||
void reset();
|
||||
void setup_lcg(uint32_t lcid, uint32_t new_lcg);
|
||||
void set_priority(uint32_t lcid, uint32_t priority);
|
||||
void timer_expired(uint32_t timer_id);
|
||||
|
||||
typedef enum {
|
||||
LONG_BSR,
|
||||
SHORT_BSR,
|
||||
TRUNC_BSR
|
||||
} bsr_format_t;
|
||||
|
||||
typedef struct {
|
||||
bsr_format_t format;
|
||||
uint32_t buff_size[4];
|
||||
} bsr_t;
|
||||
|
||||
bool need_to_send_bsr_on_ul_grant(uint32_t nof_grant_bytes, uint32_t nof_padding_bytes, bsr_t *bsr);
|
||||
bool need_to_send_sr();
|
||||
|
||||
private:
|
||||
|
||||
bool is_pending_sr;
|
||||
mac_params *params_db;
|
||||
mac_io *mac_io_h;
|
||||
timers *timers_db;
|
||||
log *log_h;
|
||||
bool initiated;
|
||||
const static int MAX_LCID = 20;
|
||||
uint32_t lcg[MAX_LCID];
|
||||
uint32_t priorities[MAX_LCID];
|
||||
uint32_t find_max_priority_lcid();
|
||||
enum {NONE, REGULAR, PADDING, PERIODIC} triggered_bsr_type;
|
||||
bool timer_periodic;
|
||||
bool timer_retx;
|
||||
|
||||
bsr_t pending_bsr;
|
||||
bool sr_is_sent;
|
||||
bool check_all_channels();
|
||||
bool check_highest_channel();
|
||||
void get_pending_bsr_format(uint32_t nof_padding_bytes);
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,57 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "srsapps/ue/mac/proc.h"
|
||||
|
||||
#ifndef PROCPHR_H
|
||||
#define PROCPHR_H
|
||||
|
||||
/* Power headroom report procedure */
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
class phr_proc : public proc
|
||||
{
|
||||
public:
|
||||
void step(uint32_t tti) {
|
||||
if (is_running()) {
|
||||
fprintf(stderr, "PHR procedure not implemented\n");
|
||||
}
|
||||
}
|
||||
void reset() {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,165 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "srsapps/ue/phy/phy.h"
|
||||
#include "srsapps/common/log.h"
|
||||
#include "srsapps/ue/mac/mac_params.h"
|
||||
#include "srsapps/common/qbuff.h"
|
||||
#include "srsapps/ue/mac/proc.h"
|
||||
#include "srsapps/common/timers.h"
|
||||
#include "srsapps/ue/mac/mux.h"
|
||||
#include "srsapps/ue/mac/demux.h"
|
||||
#include "srsapps/ue/mac/pdu.h"
|
||||
|
||||
#ifndef PROCRA_H
|
||||
#define PROCRA_H
|
||||
|
||||
/* Random access procedure as specified in Section 5.1 of 36.321 */
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
class ra_proc : public proc,timer_callback
|
||||
{
|
||||
public:
|
||||
ra_proc() : rar_pdu_msg(20) {};
|
||||
bool init(mac_params *params_db, phy *phy_h, log *log_h, timers *timers_db,
|
||||
mux *mux_unit, demux *demux_unit);
|
||||
void reset();
|
||||
void start_pdcch_order();
|
||||
void start_rlc_order();
|
||||
void start_mac_order();
|
||||
void step(uint32_t tti);
|
||||
bool is_successful();
|
||||
bool is_response_error();
|
||||
bool is_contention_resolution();
|
||||
bool is_error();
|
||||
bool in_progress();
|
||||
void pdcch_to_crnti(bool is_ul_grant);
|
||||
void timer_expired(uint32_t timer_id);
|
||||
|
||||
private:
|
||||
|
||||
void process_timeadv_cmd(uint32_t ta_cmd);
|
||||
void step_initialization();
|
||||
void step_initialization_wait();
|
||||
void step_resource_selection();
|
||||
void step_preamble_transmission();
|
||||
void step_response_reception();
|
||||
void step_response_error();
|
||||
void step_backoff_wait();
|
||||
void step_contention_resolution();
|
||||
void step_completition();
|
||||
|
||||
// Buffer to receive RAR PDU
|
||||
static const uint32_t MAX_RAR_PDU_LEN = 2048;
|
||||
uint8_t rar_pdu_buffer[MAX_RAR_PDU_LEN];
|
||||
rar_pdu rar_pdu_msg;
|
||||
|
||||
// Random Access parameters provided by higher layers defined in 5.1.1
|
||||
// They are read from params_db during initialization init()
|
||||
uint32_t configIndex;
|
||||
uint32_t nof_preambles;
|
||||
uint32_t nof_groupA_preambles;
|
||||
uint32_t nof_groupB_preambles;
|
||||
uint32_t messagePowerOffsetGroupB;
|
||||
uint32_t messageSizeGroupA;
|
||||
uint32_t Pcmax;
|
||||
uint32_t deltaPreambleMsg3;
|
||||
uint32_t responseWindowSize;
|
||||
uint32_t powerRampingStep;
|
||||
uint32_t preambleTransMax;
|
||||
uint32_t iniReceivedTargetPower;
|
||||
int delta_preamble_db;
|
||||
uint32_t contentionResolutionTimer;
|
||||
uint32_t maskIndex;
|
||||
int preambleIndex;
|
||||
|
||||
// Internal variables
|
||||
uint32_t tti;
|
||||
uint32_t preambleTransmissionCounter;
|
||||
uint32_t backoff_param_ms;
|
||||
uint32_t sel_maskIndex;
|
||||
uint32_t sel_preamble;
|
||||
uint32_t backoff_interval_start;
|
||||
uint32_t backoff_inteval;
|
||||
int received_target_power_dbm;
|
||||
uint32_t ra_rnti;
|
||||
uint8_t payload[256]; // 56 bits is often enough
|
||||
|
||||
enum {
|
||||
IDLE = 0,
|
||||
INITIALIZATION, // Section 5.1.1
|
||||
INITIALIZATION_WAIT,
|
||||
RESOURCE_SELECTION, // Section 5.1.2
|
||||
PREAMBLE_TRANSMISSION, // Section 5.1.3
|
||||
RESPONSE_RECEPTION, // Section 5.1.4
|
||||
RESPONSE_ERROR,
|
||||
BACKOFF_WAIT,
|
||||
CONTENTION_RESOLUTION, // Section 5.1.5
|
||||
COMPLETION, // Section 5.1.6
|
||||
RA_PROBLEM // Section 5.1.5 last part
|
||||
} state;
|
||||
|
||||
typedef enum {RA_GROUP_A, RA_GROUP_B} ra_group_t;
|
||||
|
||||
ra_group_t last_msg3_group;
|
||||
bool msg3_transmitted;
|
||||
bool first_rar_received;
|
||||
void read_params();
|
||||
|
||||
phy *phy_h;
|
||||
log *log_h;
|
||||
mac_params *params_db;
|
||||
timers *timers_db;
|
||||
mux *mux_unit;
|
||||
demux *demux_unit;
|
||||
|
||||
pthread_t pt_init_prach;
|
||||
|
||||
uint64_t transmitted_contention_id;
|
||||
uint16_t transmitted_crnti;
|
||||
enum {
|
||||
PDCCH_CRNTI_NOT_RECEIVED = 0,
|
||||
PDCCH_CRNTI_UL_GRANT,
|
||||
PDCCH_CRNTI_DL_GRANT
|
||||
} pdcch_to_crnti_received;
|
||||
|
||||
enum {
|
||||
PDCCH_ORDER = 0,
|
||||
RLC_ORDER,
|
||||
MAC_ORDER
|
||||
} start_mode;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,65 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "srsapps/ue/mac/proc.h"
|
||||
#include "srsapps/ue/phy/phy.h"
|
||||
#include "srsapps/ue/mac/mac_params.h"
|
||||
|
||||
#ifndef PROCSR_H
|
||||
#define PROCSR_H
|
||||
|
||||
/* Scheduling Request procedure as defined in 5.4.4 of 36.321 */
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
class sr_proc : public proc
|
||||
{
|
||||
public:
|
||||
sr_proc();
|
||||
void init(log *log_h, mac_params *params_db, phy *phy_h);
|
||||
void step(uint32_t tti);
|
||||
void reset();
|
||||
void start();
|
||||
bool need_random_access();
|
||||
private:
|
||||
uint32_t sr_counter;
|
||||
uint32_t dsr_transmax;
|
||||
bool is_pending_sr;
|
||||
mac_params *params_db;
|
||||
phy *phy_h;
|
||||
log *log_h;
|
||||
bool initiated;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,108 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include "srsapps/ue/phy/phy.h"
|
||||
#include "srsapps/common/log.h"
|
||||
#include "srsapps/ue/mac/mac_params.h"
|
||||
#include "srsapps/ue/mac/mux.h"
|
||||
#include "srsapps/common/timers.h"
|
||||
|
||||
#ifndef ULHARQ_H
|
||||
#define ULHARQ_H
|
||||
|
||||
/* Uplink HARQ entity as defined in 5.4.2 of 36.321 */
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
typedef _Complex float cf_t;
|
||||
|
||||
class ul_harq_entity
|
||||
{
|
||||
public:
|
||||
|
||||
const static uint32_t NOF_HARQ_PROC = 8;
|
||||
static uint32_t pidof(uint32_t tti);
|
||||
|
||||
bool init(srslte_cell_t cell, mac_params *params_db, log *log_h, timers* timers_, mux *mux_unit);
|
||||
|
||||
void reset();
|
||||
void reset_ndi();
|
||||
bool is_sps(uint32_t pid);
|
||||
void run_tti(uint32_t tti, ul_sched_grant *grant, phy *phy_);
|
||||
void run_tti(uint32_t tti, phy *phy_);
|
||||
|
||||
private:
|
||||
|
||||
class ul_harq_process {
|
||||
public:
|
||||
ul_harq_process();
|
||||
bool init(srslte_cell_t cell, ul_harq_entity *parent);
|
||||
void reset();
|
||||
void reset_ndi();
|
||||
|
||||
void generate_retx(uint32_t tti_tx, ul_buffer *ul);
|
||||
void generate_retx(uint32_t tti_tx, ul_sched_grant *ul_grant, ul_buffer *ul);
|
||||
void generate_new_tx(uint32_t tti_tx, uint8_t *payload, bool is_msg3, ul_sched_grant* grant, ul_buffer *ul);
|
||||
|
||||
uint32_t get_rv();
|
||||
bool has_grant();
|
||||
ul_sched_grant *get_grant();
|
||||
void set_harq_feedback(bool ack);
|
||||
bool get_ndi();
|
||||
uint32_t last_tx_tti();
|
||||
|
||||
private:
|
||||
uint32_t current_tx_nb;
|
||||
uint32_t current_irv;
|
||||
bool harq_feedback;
|
||||
bool ndi;
|
||||
log *log_h;
|
||||
ul_harq_entity *harq_entity;
|
||||
ul_sched_grant cur_grant;
|
||||
bool is_grant_configured;
|
||||
srslte_softbuffer_tx_t softbuffer;
|
||||
bool is_msg3;
|
||||
bool is_initiated;
|
||||
uint32_t tti_last_tx;
|
||||
|
||||
void generate_tx(uint32_t tti_tx, uint8_t *pdu_payload, ul_buffer* ul);
|
||||
};
|
||||
|
||||
timers *timers_db;
|
||||
mux *mux_unit;
|
||||
ul_harq_process proc[NOF_HARQ_PROC];
|
||||
log *log_h;
|
||||
mac_params *params_db;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,59 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include "srsapps/common/log.h"
|
||||
#include "srsapps/ue/phy/phy.h"
|
||||
#include "srsapps/ue/mac/mac_params.h"
|
||||
#include "srsapps/common/timers.h"
|
||||
|
||||
#ifndef ULSPS_H
|
||||
#define ULSPS_H
|
||||
|
||||
/* Uplink Semi-Persistent schedulign (Section 5.10.2) */
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
typedef _Complex float cf_t;
|
||||
|
||||
class ul_sps
|
||||
{
|
||||
public:
|
||||
|
||||
void clear() {}
|
||||
void reset(uint32_t tti, sched_grant *grant) {}
|
||||
ul_sched_grant *get_pending_grant(uint32_t tti) { return NULL; }
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,203 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "srsapps/ue/mac/mac.h"
|
||||
#include "srsapps/ue/mac/demux.h"
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
demux::demux() : mac_msg(20),pending_mac_msg(20)
|
||||
{
|
||||
contention_resolution_id = 0;
|
||||
pending_temp_rnti = false;
|
||||
has_pending_contention_resolution_id = false;
|
||||
sdu_handler_ = NULL;
|
||||
}
|
||||
|
||||
void demux::init(phy* phy_h_, log* log_h_, mac_io* mac_io_h_, timers* timers_db_)
|
||||
{
|
||||
phy_h = phy_h_;
|
||||
log_h = log_h_;
|
||||
mac_io_h = mac_io_h_;
|
||||
timers_db = timers_db_;
|
||||
}
|
||||
|
||||
void demux::add_sdu_handler(sdu_handler* handler)
|
||||
{
|
||||
sdu_handler_ = handler;
|
||||
}
|
||||
|
||||
bool demux::is_temp_crnti_pending()
|
||||
{
|
||||
return pending_temp_rnti;
|
||||
}
|
||||
|
||||
bool demux::is_contention_resolution_id_pending() {
|
||||
return has_pending_contention_resolution_id;
|
||||
}
|
||||
|
||||
uint64_t demux::get_contention_resolution_id()
|
||||
{
|
||||
uint64_t x = contention_resolution_id;
|
||||
contention_resolution_id = 0;
|
||||
has_pending_contention_resolution_id = false;
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
/* Demultiplexing of MAC PDU associated with SI-RNTI. The PDU passes through
|
||||
* the MAC in transparent mode
|
||||
*/
|
||||
void demux::push_pdu_bcch(uint8_t *mac_pdu, uint32_t nof_bits)
|
||||
{
|
||||
mac_io_h->get(mac_io::MAC_LCH_BCCH_DL)->send(mac_pdu, nof_bits);
|
||||
Debug("Pushed BCCH MAC PDU in transparent mode\n");
|
||||
}
|
||||
|
||||
/* Demultiplexing of MAC PDU associated with a Temporal C-RNTI. The PDU will
|
||||
* remain in buffer until demultiplex_pending_pdu() is called.
|
||||
* This features is provided to enable the Random Access Procedure to decide
|
||||
* wether the PDU shall pass to upper layers or not, which depends on the
|
||||
* Contention Resolution result
|
||||
*/
|
||||
void demux::push_pdu_temp_crnti(uint8_t *mac_pdu, uint32_t nof_bits)
|
||||
{
|
||||
if (!pending_temp_rnti) {
|
||||
// Unpack DLSCH MAC PDU
|
||||
pending_mac_msg.init(nof_bits/8);
|
||||
pending_mac_msg.parse_packet(mac_pdu);
|
||||
|
||||
// Look for Contention Resolution UE ID
|
||||
while(pending_mac_msg.next()) {
|
||||
if (pending_mac_msg.get()->ce_type() == sch_subh::CON_RES_ID) {
|
||||
contention_resolution_id = pending_mac_msg.get()->get_con_res_id();
|
||||
has_pending_contention_resolution_id = true;
|
||||
Info("Found Contention Resolution ID CE\n");
|
||||
}
|
||||
}
|
||||
pending_mac_msg.reset();
|
||||
pending_temp_rnti = true;
|
||||
Info("Saved MAC PDU with Temporal C-RNTI in buffer\n");
|
||||
} else {
|
||||
Warning("Error pushing PDU with Temporal C-RNTI: Another PDU is still in pending\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Demultiplexing of logical channels and dissassemble of MAC CE */
|
||||
void demux::push_pdu(uint8_t *mac_pdu, uint32_t nof_bits)
|
||||
{
|
||||
// Unpack DLSCH MAC PDU
|
||||
mac_msg.init(nof_bits/8);
|
||||
mac_msg.parse_packet(mac_pdu);
|
||||
process_pdu(&mac_msg);
|
||||
Debug("Normal MAC PDU processed\n");
|
||||
}
|
||||
|
||||
void demux::discard_pending_pdu()
|
||||
{
|
||||
pending_temp_rnti = false;
|
||||
pending_mac_msg.reset();
|
||||
}
|
||||
|
||||
void demux::demultiplex_pending_pdu()
|
||||
{
|
||||
if (pending_temp_rnti) {
|
||||
process_pdu(&pending_mac_msg);
|
||||
discard_pending_pdu();
|
||||
Info("Temporal C-RNTI MAC PDU processed\n");
|
||||
} else {
|
||||
Error("Error demultiplex pending PDU: No pending PDU\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void demux::process_pdu(sch_pdu *pdu_msg)
|
||||
{
|
||||
Info("Processing PDU\n");
|
||||
while(pdu_msg->next()) {
|
||||
if (pdu_msg->get()->is_sdu()) {
|
||||
// Route logical channel
|
||||
if (pdu_msg->get()->get_sdu_lcid() <= mac_io::MAC_LCH_DTCH2_DL) {
|
||||
qbuff *dest_lch = mac_io_h->get(pdu_msg->get()->get_sdu_lcid());
|
||||
if (dest_lch) {
|
||||
dest_lch->send(pdu_msg->get()->get_sdu_ptr(), pdu_msg->get()->get_sdu_nbytes()*8);
|
||||
Info("Sent MAC SDU len=%d bytes to lchid=%d\n",
|
||||
pdu_msg->get()->get_sdu_nbytes(), pdu_msg->get()->get_sdu_lcid());
|
||||
} else {
|
||||
Error("Getting destination channel LCID=%d\n", pdu_msg->get()->get_sdu_lcid());
|
||||
}
|
||||
} else {
|
||||
Warning("Received SDU for unsupported LCID=%d\n", pdu_msg->get()->get_sdu_lcid());
|
||||
}
|
||||
// Process MAC Control Element
|
||||
} else {
|
||||
if (!process_ce(pdu_msg->get())) {
|
||||
Warning("Received Subheader with invalid or unkonwn LCID\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
/* notify handler if registred */
|
||||
if (sdu_handler_) {
|
||||
pdu_msg->reset();
|
||||
while(pdu_msg->next()) {
|
||||
if (pdu_msg->get()->is_sdu()) {
|
||||
sdu_handler_->notify_new_sdu(pdu_msg->get()->get_sdu_lcid());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool demux::process_ce(sch_subh *subh) {
|
||||
switch(subh->ce_type()) {
|
||||
case sch_subh::CON_RES_ID:
|
||||
contention_resolution_id = subh->get_c_rnti();
|
||||
Debug("Saved Contention Resolution ID=%d\n", contention_resolution_id);
|
||||
break;
|
||||
case sch_subh::TA_CMD:
|
||||
phy_h->set_timeadv(subh->get_ta_cmd());
|
||||
|
||||
// Start or restart timeAlignmentTimer
|
||||
timers_db->get(mac::TIME_ALIGNMENT)->reset();
|
||||
timers_db->get(mac::TIME_ALIGNMENT)->run();
|
||||
Debug("Set TimeAdvance Command %d\n", subh->get_ta_cmd());
|
||||
break;
|
||||
case sch_subh::PADDING:
|
||||
break;
|
||||
default:
|
||||
Error("MAC CE 0x%x not supported\n", subh->ce_type());
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,223 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "srsapps/ue/phy/phy.h"
|
||||
#include "srsapps/ue/phy/dl_sched_grant.h"
|
||||
|
||||
#include "srsapps/ue/mac/mac.h"
|
||||
#include "srsapps/ue/mac/dl_harq.h"
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
|
||||
/***********************************************************
|
||||
*
|
||||
* HARQ ENTITY
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
dl_harq_entity::dl_harq_entity()
|
||||
{
|
||||
for (uint32_t i=0;i<NOF_HARQ_PROC+1;i++) {
|
||||
proc[i].pid = i;
|
||||
}
|
||||
pending_ack_pid = -1;
|
||||
}
|
||||
bool dl_harq_entity::init(srslte_cell_t cell, uint32_t max_payload_len, log* log_h_, timers* timers_, demux *demux_unit_)
|
||||
{
|
||||
timers_db = timers_;
|
||||
demux_unit = demux_unit_;
|
||||
log_h = log_h_;
|
||||
for (uint32_t i=0;i<NOF_HARQ_PROC+1;i++) {
|
||||
if (!proc[i].init(cell, max_payload_len, this)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
bool dl_harq_entity::is_sps(uint32_t pid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
void dl_harq_entity::set_harq_info(uint32_t pid, dl_sched_grant* grant)
|
||||
{
|
||||
proc[pid%(NOF_HARQ_PROC+1)].set_harq_info(grant);
|
||||
}
|
||||
|
||||
void dl_harq_entity::receive_data(uint32_t tti, uint32_t pid, dl_buffer* dl_buffer, phy* phy_h)
|
||||
{
|
||||
proc[pid%(NOF_HARQ_PROC+1)].receive_data(tti, dl_buffer, phy_h);
|
||||
}
|
||||
|
||||
void dl_harq_entity::reset()
|
||||
{
|
||||
for (uint32_t i=0;i<NOF_HARQ_PROC+1;i++) {
|
||||
proc[i].reset();
|
||||
}
|
||||
}
|
||||
|
||||
bool dl_harq_entity::is_ack_pending_resolution()
|
||||
{
|
||||
return pending_ack_pid >= 0;
|
||||
}
|
||||
|
||||
void dl_harq_entity::send_pending_ack_contention_resolution()
|
||||
{
|
||||
if (is_ack_pending_resolution()) {
|
||||
proc[pending_ack_pid].send_pending_ack_contention_resolution();
|
||||
pending_ack_pid = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************
|
||||
*
|
||||
* HARQ PROCESS
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
dl_harq_entity::dl_harq_process::dl_harq_process() : cur_grant(0),pending_ack_grant(0) {
|
||||
is_first_tx = true;
|
||||
is_first_decoded = true;
|
||||
is_initiated = false;
|
||||
bzero(&cur_grant, sizeof(srslte::ue::dl_sched_grant));
|
||||
payload = NULL;
|
||||
max_payload_len = 0;
|
||||
}
|
||||
|
||||
void dl_harq_entity::dl_harq_process::reset() {
|
||||
is_first_tx = true;
|
||||
is_first_decoded = true;
|
||||
bzero(&cur_grant, sizeof(srslte::ue::dl_sched_grant));
|
||||
if (is_initiated) {
|
||||
srslte_softbuffer_rx_reset(&softbuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void dl_harq_entity::dl_harq_process::send_pending_ack_contention_resolution()
|
||||
{
|
||||
if (pending_ul_buffer) {
|
||||
Info("Generating Pending ACK=%d for UL TTI=%d\n", pending_ack, pending_ul_buffer->tti);
|
||||
pending_ul_buffer->generate_ack(pending_ack, &pending_ack_grant);
|
||||
}
|
||||
}
|
||||
|
||||
void dl_harq_entity::dl_harq_process::receive_data(uint32_t tti, srslte::ue::dl_buffer *dl_buffer, phy *phy_h)
|
||||
{
|
||||
bool ack = false;
|
||||
pending_ul_buffer = NULL;
|
||||
|
||||
if (payload) {
|
||||
if (cur_grant.get_tbs() <= max_payload_len) {
|
||||
Info("Decoding PDSCH data TBS=%d, RV=%d\n", cur_grant.get_tbs(), cur_grant.get_rv());
|
||||
if (dl_buffer->decode_data(&cur_grant, &softbuffer, payload)) {
|
||||
Info("Decoded OK\n");
|
||||
// RX OK
|
||||
if (pid == HARQ_BCCH_PID) {
|
||||
Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (BCCH)\n", cur_grant.get_tbs()/8);
|
||||
harq_entity->demux_unit->push_pdu_bcch(payload, cur_grant.get_tbs());
|
||||
is_first_tx = true;
|
||||
} else {
|
||||
if (is_first_decoded) {
|
||||
if (cur_grant.is_temp_rnti()) {
|
||||
Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (Temporal C-RNTI)\n", cur_grant.get_tbs()/8);
|
||||
harq_entity->demux_unit->push_pdu_temp_crnti(payload, cur_grant.get_tbs());
|
||||
} else {
|
||||
Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit\n", cur_grant.get_tbs()/8);
|
||||
harq_entity->demux_unit->push_pdu(payload, cur_grant.get_tbs());
|
||||
}
|
||||
}
|
||||
ack = true;
|
||||
}
|
||||
} else {
|
||||
Warning("Decoded Error\n");
|
||||
// RX NOK
|
||||
ack = false;
|
||||
}
|
||||
if (pid == HARQ_BCCH_PID || harq_entity->timers_db->get(mac::TIME_ALIGNMENT)->is_expired()) {
|
||||
// Do not generate ACK
|
||||
Debug("Not generating ACK\n");
|
||||
} else {
|
||||
if (cur_grant.is_temp_rnti()) {
|
||||
// Postpone ACK after contention resolution is resolved
|
||||
pending_ack = ack;
|
||||
pending_ul_buffer = phy_h->get_ul_buffer(tti+4);
|
||||
harq_entity->pending_ack_pid = pid;
|
||||
memcpy(&pending_ack_grant, &cur_grant, sizeof(dl_sched_grant));
|
||||
Debug("ACK pending contention resolution\n");
|
||||
} else {
|
||||
Debug("Generating ACK\n");
|
||||
// Generate ACK
|
||||
srslte::ue::ul_buffer *ul_buffer = phy_h->get_ul_buffer(tti+4);
|
||||
ul_buffer->generate_ack(ack, &cur_grant);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Error with DL grant. TBS (%d) exceeds payload buffer length (%d)\n", cur_grant.get_tbs(), max_payload_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Implement 5.3.2.2
|
||||
void dl_harq_entity::dl_harq_process::set_harq_info(srslte::ue::dl_sched_grant* new_grant) {
|
||||
bool is_new_transmission = false;
|
||||
if (new_grant->get_ndi() && !cur_grant.get_ndi() || is_first_tx) {
|
||||
is_new_transmission = true;
|
||||
is_first_decoded = true;
|
||||
is_first_tx = false;
|
||||
Debug("Set HARQ Info for new transmission\n");
|
||||
} else {
|
||||
is_new_transmission = false;
|
||||
Debug("Set HARQ Info for retransmission\n");
|
||||
}
|
||||
if (is_new_transmission || cur_grant.get_tbs() != new_grant->get_tbs()) {
|
||||
Debug("Reset softbuffer RX\n");
|
||||
srslte_softbuffer_rx_reset(&softbuffer);
|
||||
}
|
||||
if (new_grant->get_tbs() <= max_payload_len) {
|
||||
memcpy(&cur_grant, new_grant, sizeof(srslte::ue::dl_sched_grant));
|
||||
} else {
|
||||
fprintf(stderr, "Error with DL grant. TBS (%d) exceeds payload buffer length (%d)\n", new_grant->get_tbs(), max_payload_len);
|
||||
}
|
||||
}
|
||||
bool dl_harq_entity::dl_harq_process::init(srslte_cell_t cell, uint32_t max_payload_len_, dl_harq_entity *parent) {
|
||||
max_payload_len = max_payload_len_;
|
||||
if (srslte_softbuffer_rx_init(&softbuffer, cell)) {
|
||||
fprintf(stderr, "Error initiating soft buffer\n");
|
||||
return false;
|
||||
} else {
|
||||
is_initiated = true;
|
||||
harq_entity = parent;
|
||||
log_h = harq_entity->log_h;
|
||||
payload = (uint8_t*) srslte_vec_malloc(sizeof(uint8_t) * max_payload_len);
|
||||
return payload?true:false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "srsapps/ue/mac/dl_sps.h"
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
dl_sched_grant* dl_sps::get_pending_grant(uint32_t tti)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
void dl_sps::reset(uint32_t tti, dl_sched_grant* grant)
|
||||
{
|
||||
|
||||
}
|
||||
void dl_sps::clear()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,524 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "srsapps/ue/phy/phy.h"
|
||||
#include "srsapps/common/log.h"
|
||||
#include "srsapps/ue/mac/mac.h"
|
||||
#include "srsapps/ue/mac/mac_params.h"
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
bool mac::init(phy *phy_h_, tti_sync* ttisync_, log* log_h_)
|
||||
{
|
||||
started = false;
|
||||
ttisync = ttisync_;
|
||||
phy_h = phy_h_;
|
||||
log_h = log_h_;
|
||||
tti = 0;
|
||||
is_synchronized = false;
|
||||
|
||||
bsr_procedure.init(log_h, &timers_db, ¶ms_db, &mac_io_lch);
|
||||
mux_unit.init(log_h, &mac_io_lch, &bsr_procedure);
|
||||
demux_unit.init(phy_h, log_h, &mac_io_lch, &timers_db);
|
||||
ra_procedure.init(¶ms_db, phy_h, log_h, &timers_db, &mux_unit, &demux_unit);
|
||||
sr_procedure.init(log_h, ¶ms_db, phy_h);
|
||||
reset();
|
||||
|
||||
pthread_attr_t attr;
|
||||
struct sched_param param;
|
||||
param.sched_priority = sched_get_priority_min(SCHED_FIFO) ;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
|
||||
pthread_attr_setschedparam(&attr, ¶m);
|
||||
|
||||
if (!pthread_create(&mac_thread, &attr, mac_thread_fnc, this)) {
|
||||
started = true;
|
||||
} else {
|
||||
perror("pthread_create");
|
||||
}
|
||||
return started;
|
||||
}
|
||||
|
||||
void mac::stop()
|
||||
{
|
||||
started = false;
|
||||
pthread_join(mac_thread, NULL);
|
||||
}
|
||||
|
||||
int mac::get_tti()
|
||||
{
|
||||
if (is_synchronized) {
|
||||
return (int) tti;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Implement Section 5.8
|
||||
void mac::reconfiguration()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Implement Section 5.9
|
||||
void mac::reset()
|
||||
{
|
||||
timers_db.stop_all();
|
||||
timeAlignmentTimerExpire();
|
||||
ul_harq.reset_ndi();
|
||||
|
||||
mux_unit.msg3_flush();
|
||||
mux_unit.reset();
|
||||
|
||||
ra_procedure.stop();
|
||||
ra_procedure.reset();
|
||||
sr_procedure.stop();
|
||||
sr_procedure.reset();
|
||||
bsr_procedure.stop();
|
||||
bsr_procedure.reset();
|
||||
phr_procedure.stop();
|
||||
phr_procedure.reset();
|
||||
|
||||
dl_harq.reset();
|
||||
params_db.set_param(mac_params::RNTI_TEMP, 0);
|
||||
}
|
||||
|
||||
void* mac::mac_thread_fnc(void *arg) {
|
||||
srslte::ue::mac* mac = static_cast<srslte::ue::mac*>(arg);
|
||||
mac->main_radio_loop();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void mac::main_radio_loop() {
|
||||
setup_timers();
|
||||
while(1) {
|
||||
if (!is_synchronized) {
|
||||
srslte_cell_t cell;
|
||||
uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN];
|
||||
|
||||
if (phy_h->decode_mib_best(&cell, bch_payload)) {
|
||||
|
||||
// Print MIB
|
||||
srslte_cell_fprint(stdout, &cell, phy_h->get_current_tti()/10);
|
||||
|
||||
// Init HARQ for this cell
|
||||
Info("Init UL/DL HARQ\n");
|
||||
ul_harq.init(cell, ¶ms_db, log_h, &timers_db, &mux_unit);
|
||||
dl_harq.init(cell, 8*1024, log_h, &timers_db, &demux_unit);
|
||||
|
||||
// Set the current PHY cell to the detected cell
|
||||
Info("Setting up PHY for cell_id=%d\n", cell.id);
|
||||
if (phy_h->set_cell(cell)) {
|
||||
Info("Starting RX streaming\n");
|
||||
if (phy_h->start_rxtx()) {
|
||||
log_h->step(ttisync->wait());
|
||||
|
||||
Info("Receiver synchronized\n");
|
||||
|
||||
// Send MIB to RRC
|
||||
mac_io_lch.get(mac_io::MAC_LCH_BCCH_DL)->send(bch_payload, SRSLTE_BCH_PAYLOAD_LEN);
|
||||
|
||||
ttisync->resync();
|
||||
Info("Wait for AGC, CFO estimation, etc. \n");
|
||||
for (int i=0;i<1000;i++) {
|
||||
tti = ttisync->wait();
|
||||
}
|
||||
is_synchronized = true;
|
||||
} else {
|
||||
Error("Starting PHY receiver\n");
|
||||
exit(-1);
|
||||
}
|
||||
} else {
|
||||
Error("Setting PHY cell\n");
|
||||
exit(-1);
|
||||
}
|
||||
} else {
|
||||
Warning("Cell not found\n");
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
if (is_synchronized) {
|
||||
/* Warning: Here order of invocation of procedures is important!! */
|
||||
bool ul_resources_available;
|
||||
tti = ttisync->wait();
|
||||
log_h->step(tti);
|
||||
|
||||
// Step all procedures
|
||||
bsr_procedure.step(tti);
|
||||
|
||||
// Check if BSR procedure need to start SR
|
||||
if (bsr_procedure.need_to_send_sr()) {
|
||||
sr_procedure.start();
|
||||
}
|
||||
sr_procedure.step(tti);
|
||||
|
||||
// Check SR if we need to start RA
|
||||
if (sr_procedure.need_random_access()) {
|
||||
ra_procedure.start_mac_order();
|
||||
}
|
||||
|
||||
ra_procedure.step(tti);
|
||||
|
||||
|
||||
//phr_procedure.step(tti);
|
||||
|
||||
// Receive PCH, if requested
|
||||
receive_pch(tti);
|
||||
|
||||
// Process DL grants always
|
||||
process_dl_grants(tti);
|
||||
|
||||
// Process UL grants if RA procedure is done and we have pending data or in contention resolution
|
||||
if (ra_procedure.is_contention_resolution() ||
|
||||
ra_procedure.is_successful() && mux_unit.is_pending_ccch_sdu())
|
||||
{
|
||||
ul_resources_available = process_ul_grants(tti);
|
||||
}
|
||||
|
||||
// Send pending HARQ ACK, if any, and contention resolution is resolved
|
||||
if (dl_harq.is_ack_pending_resolution()) {
|
||||
ra_procedure.step(tti);
|
||||
if (ra_procedure.is_successful() || ra_procedure.is_response_error()) {
|
||||
Info("Sending pending ACK for contention resolution\n");
|
||||
dl_harq.send_pending_ack_contention_resolution();
|
||||
}
|
||||
}
|
||||
|
||||
timers_db.step_all();
|
||||
|
||||
// Check if there is pending CCCH SDU in Multiplexing Unit
|
||||
if (mux_unit.is_pending_ccch_sdu()) {
|
||||
// Start RA procedure
|
||||
if (!ra_procedure.in_progress() && !ra_procedure.is_successful()) {
|
||||
Info("Starting RA procedure by RLC order\n");
|
||||
ra_procedure.start_rlc_order();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mac::add_sdu_handler(sdu_handler *handler) {
|
||||
demux_unit.add_sdu_handler(handler);
|
||||
}
|
||||
|
||||
void mac::setup_timers()
|
||||
{
|
||||
if (params_db.get_param(mac_params::TIMER_TIMEALIGN) > 0) {
|
||||
timers_db.get(TIME_ALIGNMENT)->set(this, params_db.get_param(mac_params::TIMER_TIMEALIGN));
|
||||
}
|
||||
}
|
||||
static sched_grant::rnti_type_t rnti_type(int rnti_param_id) {
|
||||
switch(rnti_param_id) {
|
||||
case mac_params::RNTI_C:
|
||||
return sched_grant::RNTI_TYPE_CRNTI;
|
||||
case mac_params::RNTI_TEMP:
|
||||
return sched_grant::RNTI_TYPE_TEMP;
|
||||
case mac_params::RNTI_SPS:
|
||||
return sched_grant::RNTI_TYPE_SPS;
|
||||
case mac_params::RNTI_RA:
|
||||
return sched_grant::RNTI_TYPE_RA;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t mac::get_harq_sps_pid(uint32_t tti) {
|
||||
uint32_t nof_proc = ((uint32_t) params_db.get_param(mac_params::SPS_DL_NOF_PROC));
|
||||
return tti/params_db.get_param(mac_params::SPS_DL_SCHED_INTERVAL)%nof_proc;
|
||||
|
||||
}
|
||||
|
||||
void mac::timer_expired(uint32_t timer_id)
|
||||
{
|
||||
switch(timer_id) {
|
||||
case TIME_ALIGNMENT:
|
||||
timeAlignmentTimerExpire();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Function called on expiry of TimeAlignmentTimer */
|
||||
void mac::timeAlignmentTimerExpire() {
|
||||
dl_harq.reset();
|
||||
ul_harq.reset();
|
||||
dl_sps_assig.clear();
|
||||
ul_sps_assig.clear();
|
||||
}
|
||||
|
||||
// Receive PCH when requested as defined in Section 5.5
|
||||
void mac::receive_pch(uint32_t tti) {
|
||||
if (params_db.get_param(mac_params::PCCH_RECEIVE)) {
|
||||
dl_buffer *dl_buffer = phy_h->get_dl_buffer(tti);
|
||||
dl_sched_grant pch_grant(sched_grant::RNTI_TYPE_PRNTI, SRSLTE_PRNTI);
|
||||
if (dl_buffer->get_dl_grant(&pch_grant)) {
|
||||
qbuff *pcch_buff = mac_io_lch.get(mac_io::MAC_LCH_PCCH_DL);
|
||||
uint8_t *ptr = (uint8_t*) pcch_buff->request();
|
||||
if (ptr && pch_grant.get_tbs() <= mac_io_lch.DEFAULT_MSG_SZ) {
|
||||
if (dl_buffer->decode_data(&pch_grant, ptr)) {
|
||||
pcch_buff->release();
|
||||
} else {
|
||||
Warning("Error decoding PCH\n");
|
||||
}
|
||||
} else {
|
||||
Error("Error getting pointer from PCCH buffer\n");
|
||||
}
|
||||
} else {
|
||||
Debug("No P-RNTI grant found while looking for PCH messages\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This function controls DL Grant Assignment as specified in Section 5.3.1 in 36.321
|
||||
* and issues commands to DL harq operation
|
||||
*/
|
||||
void mac::process_dl_grants(uint32_t tti) {
|
||||
// Get DL buffer for this TTI
|
||||
dl_buffer *dl_buffer = phy_h->get_dl_buffer(tti);
|
||||
|
||||
// 5.3.1 DL Assignment reception
|
||||
for (int i = mac_params::RNTI_C;i<=mac_params::RNTI_RA;i++) {
|
||||
// Check C-RNTI, SPS-RNTI and Temporal RNTI
|
||||
if (params_db.get_param(i) != 0) {
|
||||
dl_sched_grant ue_grant(rnti_type(i), params_db.get_param(i));
|
||||
if (dl_buffer->get_dl_grant(&ue_grant)) {
|
||||
// If PDCCH for C-RNTI and RA procedure in Contention Resolution, notify it
|
||||
if (ra_procedure.is_contention_resolution() && i == mac_params::RNTI_C) {
|
||||
ra_procedure.pdcch_to_crnti(false);
|
||||
}
|
||||
if (i != mac_params::RNTI_SPS) {
|
||||
uint32_t harq_pid = ue_grant.get_harq_process();
|
||||
if (i == mac_params::RNTI_TEMP) {
|
||||
ue_grant.set_ndi(is_first_temporal);
|
||||
is_first_temporal = false;
|
||||
}
|
||||
if (i == mac_params::RNTI_C && dl_harq.is_sps(harq_pid)) {
|
||||
ue_grant.set_ndi(true);
|
||||
}
|
||||
Info("Processing DL grant TBS=%d, RNTI=%d, RV=%d\n", ue_grant.get_tbs(), ue_grant.get_rnti(), ue_grant.get_rv());
|
||||
dl_harq.set_harq_info(harq_pid, &ue_grant);
|
||||
dl_harq.receive_data(tti, harq_pid, dl_buffer, phy_h);
|
||||
} else {
|
||||
uint32_t harq_pid = get_harq_sps_pid(tti);
|
||||
if (ue_grant.get_ndi()) {
|
||||
ue_grant.set_ndi(false);
|
||||
dl_harq.set_harq_info(harq_pid, &ue_grant);
|
||||
dl_harq.receive_data(tti, harq_pid, dl_buffer, phy_h);
|
||||
} else {
|
||||
if (ue_grant.is_sps_release()) {
|
||||
dl_sps_assig.clear();
|
||||
if (timers_db.get(TIME_ALIGNMENT)->is_running()) {
|
||||
//phy_h->send_sps_ack();
|
||||
Warning("PHY Send SPS ACK not implemented\n");
|
||||
}
|
||||
} else {
|
||||
dl_sps_assig.reset(tti, &ue_grant);
|
||||
ue_grant.set_ndi(true);
|
||||
dl_harq.set_harq_info(harq_pid, &ue_grant);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Process configured DL assingments (SPS) */
|
||||
dl_sched_grant *sps_grant = dl_sps_assig.get_pending_grant(tti);
|
||||
if (sps_grant != NULL) {
|
||||
Info("Processing SPS grant\n");
|
||||
uint32_t harq_pid = get_harq_sps_pid(tti);
|
||||
sps_grant->set_ndi(true);
|
||||
dl_harq.set_harq_info(harq_pid, sps_grant);
|
||||
dl_harq.receive_data(tti, harq_pid, dl_buffer, phy_h);
|
||||
}
|
||||
|
||||
/* Process SI-RNTI */
|
||||
uint32_t si_window_start = params_db.get_param(mac_params::BCCH_SI_WINDOW_ST);
|
||||
uint32_t si_window_length = params_db.get_param(mac_params::BCCH_SI_WINDOW_LEN);
|
||||
|
||||
if (tti >= si_window_start && tti < (si_window_start + si_window_length)) {
|
||||
// Exclude subf 5 and sfn%2==0 unless it's a SIB1 message (window_length=1) (This is defined in 36.331 Sec 5.2.3)
|
||||
if (!(phy_h->tti_to_subf(si_window_length) != 1 &&
|
||||
phy_h->tti_to_subf(si_window_start) == 5 && (phy_h->tti_to_SFN(tti)%2) == 0))
|
||||
{
|
||||
Info("Searching for DL grant for SI-RNTI window_st=%d, window_len=%d\n", si_window_start, si_window_length);
|
||||
dl_sched_grant si_grant(sched_grant::RNTI_TYPE_SIRNTI, SRSLTE_SIRNTI);
|
||||
if (dl_buffer->get_dl_grant(&si_grant)) {
|
||||
uint32_t k;
|
||||
if (phy_h->tti_to_subf(si_window_start) == 5) { // This is SIB1, k is different
|
||||
k = (phy_h->tti_to_SFN(tti)/2)%4;
|
||||
} else {
|
||||
k = phy_h->tti_to_subf(tti)%4;
|
||||
}
|
||||
si_grant.set_rv(((uint32_t) ceilf((float)1.5*k))%4);
|
||||
Info("DL grant found, sending to HARQ with RV: %d\n", si_grant.get_rv());
|
||||
dl_harq.set_harq_info(dl_harq_entity::HARQ_BCCH_PID, &si_grant);
|
||||
dl_harq.receive_data(tti, dl_harq_entity::HARQ_BCCH_PID, dl_buffer, phy_h);
|
||||
params_db.set_param(mac_params::BCCH_SI_WINDOW_ST, 0);
|
||||
params_db.set_param(mac_params::BCCH_SI_WINDOW_LEN, 0);
|
||||
} else {
|
||||
Warning("DL grant not found\n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* UL Grant reception and processin as defined in Section 5.4.1 in 36.321 */
|
||||
bool mac::process_ul_grants(uint32_t tti) {
|
||||
// Get DL buffer for this TTI to look for DCI grants
|
||||
dl_buffer *dl_buffer = phy_h->get_dl_buffer(tti);
|
||||
|
||||
//if (timers_db.get(TIME_ALIGNMENT)->is_running()) {
|
||||
if (1) {
|
||||
for (int i = mac_params::RNTI_C;i<=mac_params::RNTI_TEMP;i++) {
|
||||
// Check C-RNTI, SPS-RNTI and Temporal C-RNTI
|
||||
if (params_db.get_param(i) != 0) {
|
||||
ul_sched_grant ul_grant(rnti_type(i), params_db.get_param(i));
|
||||
if (dl_buffer->get_ul_grant(&ul_grant)) {
|
||||
if (ul_grant.is_from_rar()) {
|
||||
dl_buffer->discard_pending_rar_grant();
|
||||
}
|
||||
if (ra_procedure.is_contention_resolution() && i == mac_params::RNTI_C) {
|
||||
ra_procedure.pdcch_to_crnti(true);
|
||||
}
|
||||
if (i == mac_params::RNTI_C || i == mac_params::RNTI_TEMP || ra_procedure.is_running()) {
|
||||
if (i == mac_params::RNTI_C && ul_harq.is_sps(tti)) {
|
||||
ul_grant.set_ndi(true);
|
||||
}
|
||||
Info("Found UL Grant TBS=%d RNTI=%d is_from_rar=%d\n", ul_grant.get_tbs(), params_db.get_param(i), ul_grant.is_from_rar());
|
||||
ul_harq.run_tti(tti, &ul_grant, phy_h);
|
||||
return true;
|
||||
}
|
||||
else if (i == mac_params::RNTI_SPS) {
|
||||
if (ul_grant.get_ndi()) {
|
||||
ul_grant.set_ndi(false);
|
||||
ul_harq.run_tti(tti, &ul_grant, phy_h);
|
||||
} else {
|
||||
if (ul_grant.is_sps_release()) {
|
||||
ul_sps_assig.clear();
|
||||
} else {
|
||||
ul_sps_assig.reset(tti, &ul_grant);
|
||||
ul_grant.set_ndi(true);
|
||||
ul_harq.run_tti(tti, &ul_grant, phy_h);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Process configured UL assingments (SPS) */
|
||||
ul_sched_grant *sps_grant = ul_sps_assig.get_pending_grant(tti);
|
||||
if (sps_grant != NULL) {
|
||||
sps_grant->set_ndi(true);
|
||||
ul_harq.run_tti(tti, sps_grant, phy_h);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
ul_harq.run_tti(tti, phy_h);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int mac::recv_sdu(uint32_t lcid, uint8_t* sdu_payload, uint32_t nbytes)
|
||||
{
|
||||
if (lcid <= mac_io::MAC_LCH_PCCH_DL) {
|
||||
return mac_io_lch.get(lcid)->recv(sdu_payload, nbytes);
|
||||
} else {
|
||||
Error("Receiving SDU: Invalid lcid=%d\n", lcid);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int mac::recv_bcch_sdu(uint8_t* sdu_payload, uint32_t buffer_len_nbytes)
|
||||
{
|
||||
return mac_io_lch.get(mac_io::MAC_LCH_BCCH_DL)->recv(sdu_payload, buffer_len_nbytes);
|
||||
}
|
||||
|
||||
int mac::recv_ccch_sdu(uint8_t* sdu_payload, uint32_t buffer_len_nbytes)
|
||||
{
|
||||
return mac_io_lch.get(mac_io::MAC_LCH_CCCH_DL)->recv(sdu_payload, buffer_len_nbytes);
|
||||
}
|
||||
|
||||
int mac::recv_dtch0_sdu(uint8_t* sdu_payload, uint32_t buffer_len_nbytes)
|
||||
{
|
||||
return mac_io_lch.get(mac_io::MAC_LCH_DTCH0_DL)->recv(sdu_payload, buffer_len_nbytes);
|
||||
}
|
||||
|
||||
int mac::recv_dcch0_sdu(uint8_t* sdu_payload, uint32_t buffer_len_nbytes)
|
||||
{
|
||||
return mac_io_lch.get(mac_io::MAC_LCH_DTCH0_DL)->recv(sdu_payload, buffer_len_nbytes);
|
||||
}
|
||||
|
||||
|
||||
bool mac::send_sdu(uint32_t lcid, uint8_t* sdu_payload, uint32_t nbytes)
|
||||
{
|
||||
lcid += mac_io::MAC_LCH_CCCH_UL;
|
||||
if (lcid <= mac_io::MAC_LCH_DTCH2_UL) {
|
||||
return mac_io_lch.get(lcid)->send(sdu_payload, nbytes);
|
||||
} else {
|
||||
Error("Receiving SDU: Invalid lcid=%d\n", lcid);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool mac::send_ccch_sdu(uint8_t* sdu_payload, uint32_t nbytes)
|
||||
{
|
||||
return mac_io_lch.get(mac_io::MAC_LCH_CCCH_UL)->send(sdu_payload, nbytes);
|
||||
}
|
||||
|
||||
bool mac::send_dtch0_sdu(uint8_t* sdu_payload, uint32_t nbytes)
|
||||
{
|
||||
return mac_io_lch.get(mac_io::MAC_LCH_DTCH0_UL)->send(sdu_payload, nbytes);
|
||||
}
|
||||
|
||||
bool mac::send_dcch0_sdu(uint8_t* sdu_payload, uint32_t nbytes)
|
||||
{
|
||||
return mac_io_lch.get(mac_io::MAC_LCH_DCCH0_UL)->send(sdu_payload, nbytes);
|
||||
}
|
||||
|
||||
void mac::set_param(mac_params::mac_param_t param, int64_t value)
|
||||
{
|
||||
params_db.set_param((uint32_t) param, value);
|
||||
}
|
||||
|
||||
void mac::setup_lcid(uint32_t lcid, uint32_t lcg, uint32_t priority, int PBR_x_tti, uint32_t BSD)
|
||||
{
|
||||
mux_unit.set_priority(mac_io::MAC_LCH_CCCH_UL+lcid, priority, PBR_x_tti, BSD);
|
||||
bsr_procedure.setup_lcg(lcid, lcg);
|
||||
bsr_procedure.set_priority(lcid, priority);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,347 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "srsapps/ue/mac/mux.h"
|
||||
#include "srsapps/ue/mac/mac.h"
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
#define IO_IDX(lch) (lch + mac_io::MAC_LCH_CCCH_UL)
|
||||
#define UL_IDX(lch) (lch - mac_io::MAC_LCH_CCCH_UL)
|
||||
|
||||
mux::mux() : pdu_msg(20)
|
||||
{
|
||||
msg3_buff.init(1, MSG3_BUFF_SZ);
|
||||
pdu_buff.init(1, PDU_BUFF_SZ);
|
||||
bzero(nof_tx_pkts, sizeof(uint32_t) * mac_io::NOF_UL_LCH);
|
||||
pthread_mutex_init(&mutex, NULL);
|
||||
msg3_has_been_transmitted = false;
|
||||
|
||||
for (int i=0;i<mac_io::NOF_UL_LCH;i++) {
|
||||
priority[i] = 1;
|
||||
priority_sorted[i] = 1;
|
||||
PBR[i] = -1; // -1 is infinite
|
||||
BSD[i] = 10;
|
||||
lchid_sorted[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
void mux::init(log *log_h_, mac_io *mac_io_h_, bsr_proc *bsr_procedure_)
|
||||
{
|
||||
log_h = log_h_;
|
||||
mac_io_h = mac_io_h_;
|
||||
bsr_procedure = bsr_procedure_;
|
||||
}
|
||||
|
||||
void mux::reset()
|
||||
{
|
||||
for (int i=0;i<mac_io::NOF_UL_LCH;i++) {
|
||||
Bj[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool mux::is_pending_ccch_sdu()
|
||||
{
|
||||
return is_pending_sdu(0);
|
||||
}
|
||||
|
||||
bool mux::is_pending_any_sdu()
|
||||
{
|
||||
for (int i=0;i<mac_io::NOF_UL_LCH;i++) {
|
||||
if (!mac_io_h->get(i)->isempty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool mux::is_pending_sdu(uint32_t lch_id) {
|
||||
lch_id += (uint32_t) mac_io::MAC_LCH_CCCH_UL;
|
||||
if (lch_id < mac_io::MAC_NOF_QUEUES) {
|
||||
return !mac_io_h->get(lch_id)->isempty();
|
||||
}
|
||||
}
|
||||
|
||||
void mux::set_priority(uint32_t lch_id, uint32_t set_priority, int set_PBR, uint32_t set_BSD)
|
||||
{
|
||||
pthread_mutex_lock(&mutex);
|
||||
if (lch_id < mac_io::NOF_UL_LCH) {
|
||||
priority[lch_id] = set_priority;
|
||||
PBR[lch_id] = set_PBR;
|
||||
BSD[lch_id] = set_BSD;
|
||||
|
||||
// Insert priority in sorted idx array
|
||||
int new_index = 0;
|
||||
while(set_priority > priority_sorted[new_index] && new_index < mac_io::NOF_UL_LCH) {
|
||||
new_index++;
|
||||
}
|
||||
int old_index = 0;
|
||||
while(lch_id != lchid_sorted[old_index] && new_index < mac_io::NOF_UL_LCH) {
|
||||
old_index++;
|
||||
}
|
||||
if (new_index == mac_io::NOF_UL_LCH) {
|
||||
Error("Can't find LchID=%d in sorted list\n", lch_id);
|
||||
return;
|
||||
}
|
||||
// Replace goes in one direction or the other
|
||||
int add=new_index>old_index?1:-1;
|
||||
for (int i=old_index;i!=new_index;i+=add) {
|
||||
priority_sorted[i] = priority_sorted[i+add];
|
||||
lchid_sorted[i] = lchid_sorted[i+add];
|
||||
}
|
||||
priority_sorted[new_index] = set_priority;
|
||||
lchid_sorted[new_index] = lch_id;
|
||||
}
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
void mux::pdu_release()
|
||||
{
|
||||
pdu_buff.release();
|
||||
}
|
||||
|
||||
bool mux::pdu_move_to_msg3(uint32_t pdu_sz)
|
||||
{
|
||||
if (pdu_buff.isempty()) {
|
||||
if (assemble_pdu(pdu_sz)) {
|
||||
if (pdu_buff.pending_data() < MSG3_BUFF_SZ) {
|
||||
pdu_buff.move_to(&msg3_buff);
|
||||
return true;
|
||||
} else {
|
||||
pdu_buff.release();
|
||||
Error("Assembled PDU size exceeds Msg3 buffer size\n");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
Error("Assembling PDU\n");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
Error("Generating PDU: PDU pending in buffer for transmission\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Multiplexing and logical channel priorization as defined in Section 5.4.3
|
||||
uint8_t* mux::pdu_pop(uint32_t pdu_sz)
|
||||
{
|
||||
if (pdu_buff.isempty()) {
|
||||
if (assemble_pdu(pdu_sz)) {
|
||||
return (uint8_t*) pdu_buff.pop();
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
Error("Generating PDU: PDU pending in buffer for transmission\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void mux::append_crnti_ce_next_tx(uint16_t crnti) {
|
||||
pending_crnti_ce = crnti;
|
||||
}
|
||||
|
||||
sch_subh::cetype bsr_format_convert(bsr_proc::bsr_format_t format) {
|
||||
switch(format) {
|
||||
case bsr_proc::LONG_BSR:
|
||||
return sch_subh::LONG_BSR;
|
||||
case bsr_proc::SHORT_BSR:
|
||||
return sch_subh::SHORT_BSR;
|
||||
case bsr_proc::TRUNC_BSR:
|
||||
return sch_subh::TRUNC_BSR;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool mux::assemble_pdu(uint32_t pdu_sz_nbits) {
|
||||
|
||||
uint8_t *buff = (uint8_t*) pdu_buff.request();
|
||||
if (!buff) {
|
||||
Error("Assembling PDU: Buffer is not available\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure pdu_sz is byte-aligned
|
||||
pdu_sz_nbits = 8*(pdu_sz_nbits/8);
|
||||
|
||||
// Acquire mutex. Cannot change priorities, PBR or BSD after assemble finishes
|
||||
pthread_mutex_lock(&mutex);
|
||||
|
||||
// Update Bj
|
||||
for (int i=0;i<mac_io::NOF_UL_LCH;i++) {
|
||||
// Add PRB unless it's infinity
|
||||
if (PBR[i] >= 0) {
|
||||
Bj[i] += PBR[i];
|
||||
}
|
||||
if (Bj[i] >= BSD[i]) {
|
||||
Bj[i] = BSD[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Logical Channel Procedure
|
||||
|
||||
uint32_t sdu_sz = 0;
|
||||
|
||||
pdu_msg.init(pdu_sz_nbits/8, true);
|
||||
|
||||
// MAC control element for C-RNTI or data from UL-CCCH
|
||||
if (!allocate_sdu(UL_IDX(mac_io::MAC_LCH_CCCH_UL), &pdu_msg)) {
|
||||
if (pending_crnti_ce) {
|
||||
if (pdu_msg.new_subh()) {
|
||||
pdu_msg.next();
|
||||
if (!pdu_msg.get()->set_c_rnti(pending_crnti_ce)) {
|
||||
Warning("Pending C-RNTI CE could not be inserted in MAC PDU\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pending_crnti_ce = 0;
|
||||
|
||||
bsr_proc::bsr_t bsr;
|
||||
bool send_bsr_normal = bsr_procedure->need_to_send_bsr_on_ul_grant(pdu_sz_nbits/8, 0, &bsr);
|
||||
|
||||
// MAC control element for BSR, with exception of BSR included for padding;
|
||||
if (send_bsr_normal) {
|
||||
pdu_msg.next();
|
||||
pdu_msg.get()->set_bsr(bsr.buff_size, bsr_format_convert(bsr.format));
|
||||
}
|
||||
|
||||
// MAC control element for PHR
|
||||
// TODO
|
||||
|
||||
// data from any Logical Channel, except data from UL-CCCH;
|
||||
// first only those with positive Bj
|
||||
for (int i=0;i<mac_io::NOF_UL_LCH;i++) {
|
||||
bool res = true;
|
||||
while ((Bj[i] > 0 || PBR[i] < 0) && res) {
|
||||
res = allocate_sdu(lchid_sorted[i], &pdu_msg, &sdu_sz);
|
||||
if (res && PBR[i] >= 0) {
|
||||
Bj[i] -= sdu_sz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If resources remain, allocate regardless of their Bj value
|
||||
for (int i=0;i<mac_io::NOF_UL_LCH;i++) {
|
||||
while (allocate_sdu(lchid_sorted[i], &pdu_msg));
|
||||
}
|
||||
|
||||
// MAC control element for BSR included for padding.
|
||||
bool send_bsr_padding = bsr_procedure->need_to_send_bsr_on_ul_grant(pdu_sz_nbits/8, pdu_msg.rem_size(), &bsr);
|
||||
if (send_bsr_padding) {
|
||||
pdu_msg.next();
|
||||
pdu_msg.get()->set_bsr(bsr.buff_size, bsr_format_convert(bsr.format));
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
/* Release all SDUs */
|
||||
for (int i=0;i<mac_io::NOF_UL_LCH;i++) {
|
||||
while(nof_tx_pkts[i] > 0) {
|
||||
mac_io_h->get(IO_IDX(i))->release();
|
||||
nof_tx_pkts[i]--;
|
||||
}
|
||||
}
|
||||
|
||||
Info("Assembled MAC PDU msg size %d bytes\n", pdu_msg.size());
|
||||
/* Generate MAC PDU and save to buffer */
|
||||
if (pdu_msg.write_packet(buff)) {
|
||||
pdu_buff.push(pdu_sz_nbits);
|
||||
} else {
|
||||
Error("Writing PDU message to packet\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mux::allocate_sdu(uint32_t lcid, sch_pdu *pdu_msg)
|
||||
{
|
||||
return allocate_sdu(lcid, pdu_msg, NULL);
|
||||
}
|
||||
bool mux::allocate_sdu(uint32_t lcid, sch_pdu *pdu_msg, uint32_t *sdu_sz)
|
||||
{
|
||||
|
||||
// Get n-th pending SDU pointer and length
|
||||
uint32_t buff_len;
|
||||
uint8_t *buff_ptr = (uint8_t*) mac_io_h->get(mac_io::MAC_LCH_CCCH_UL + lcid)->pop(&buff_len, nof_tx_pkts[lcid]);
|
||||
|
||||
if (buff_ptr) { // there is pending SDU to allocate
|
||||
if (sdu_sz) {
|
||||
*sdu_sz = buff_len;
|
||||
}
|
||||
if (pdu_msg->new_subh()) { // there is space for a new subheader
|
||||
pdu_msg->next();
|
||||
if (pdu_msg->get()->set_sdu(lcid, buff_ptr, buff_len/8)) { // new SDU could be added
|
||||
// Increase number of pop'ed packets from queue
|
||||
nof_tx_pkts[lcid]++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void mux::msg3_flush()
|
||||
{
|
||||
msg3_buff.flush();
|
||||
msg3_has_been_transmitted = false;
|
||||
}
|
||||
|
||||
void mux::msg3_transmitted()
|
||||
{
|
||||
msg3_has_been_transmitted = true;
|
||||
}
|
||||
|
||||
bool mux::msg3_is_transmitted()
|
||||
{
|
||||
return msg3_has_been_transmitted;
|
||||
}
|
||||
|
||||
/* Returns a pointer to the Msg3 buffer */
|
||||
uint8_t* mux::msg3_pop(uint32_t TB_size)
|
||||
{
|
||||
uint32_t len;
|
||||
uint8_t *msg3 = (uint8_t*) msg3_buff.pop(&len);
|
||||
if (len < TB_size) {
|
||||
// Pad with zeros without exceeding maximum buffer size
|
||||
if (TB_size <= MSG3_BUFF_SZ) {
|
||||
bzero(&msg3[len], (TB_size-len)*sizeof(uint8_t));
|
||||
} else {
|
||||
Error("Requested TB size from Msg3 buffer exceeds buffer size (%d>%d)\n", TB_size, MSG3_BUFF_SZ);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return msg3;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,610 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <strings.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "srsapps/ue/mac/pdu.h"
|
||||
#include "srslte/srslte.h"
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
|
||||
void sch_pdu::fprint(FILE* stream)
|
||||
{
|
||||
fprintf(stream, "MAC SDU for UL/DL-SCH. ");
|
||||
pdu::fprint(stream);
|
||||
}
|
||||
|
||||
void sch_subh::fprint(FILE* stream)
|
||||
{
|
||||
if (is_sdu()) {
|
||||
fprintf(stream, "SDU LCHID=%d, SDU nof_bytes=%d\n", lcid, nof_bytes);
|
||||
} else {
|
||||
switch(lcid) {
|
||||
case C_RNTI:
|
||||
fprintf(stream, "C-RNTI CE: %d\n", get_c_rnti());
|
||||
break;
|
||||
case CON_RES_ID:
|
||||
fprintf(stream, "Contention Resolution ID CE: 0x%lx\n", get_con_res_id());
|
||||
break;
|
||||
case TA_CMD:
|
||||
fprintf(stream, "Time Advance Command CE: %d\n", get_ta_cmd());
|
||||
break;
|
||||
case PADDING:
|
||||
fprintf(stream, "PADDING\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sch_pdu::parse_packet(uint8_t *ptr)
|
||||
{
|
||||
pdu::parse_packet(ptr);
|
||||
|
||||
// Correct size for last SDU
|
||||
if (nof_subheaders > 0) {
|
||||
uint32_t read_len = 0;
|
||||
for (int i=0;i<nof_subheaders-1;i++) {
|
||||
read_len += subheaders[i].size_plus_header();
|
||||
}
|
||||
if (pdu_len-read_len-1 >= 0) {
|
||||
subheaders[nof_subheaders-1].set_payload_size(pdu_len-read_len-1);
|
||||
} else {
|
||||
fprintf(stderr,"Reading MAC PDU: negative payload for last subheader\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Section 6.1.2
|
||||
bool sch_pdu::write_packet(uint8_t* ptr)
|
||||
{
|
||||
uint8_t *init_ptr = ptr;
|
||||
// Add single or two-byte padding if required
|
||||
if (rem_len == 1 || rem_len == 2) {
|
||||
sch_subh padding;
|
||||
padding.set_padding();
|
||||
for (int i=0;i<rem_len;i++) {
|
||||
padding.write_subheader(&ptr, false);
|
||||
}
|
||||
rem_len = 0;
|
||||
}
|
||||
// Find last SDU or CE
|
||||
int last_sdu = nof_subheaders-1;
|
||||
while(!subheaders[last_sdu].is_sdu() && last_sdu >= 0) {
|
||||
last_sdu--;
|
||||
}
|
||||
int last_ce = nof_subheaders-1;
|
||||
while(subheaders[last_ce].is_sdu() && last_ce >= 0) {
|
||||
last_ce--;
|
||||
}
|
||||
int last_sh = subheaders[last_sdu].is_sdu()?last_sdu:last_ce;
|
||||
// Write subheaders for MAC CE first
|
||||
for (int i=0;i<nof_subheaders;i++) {
|
||||
if (!subheaders[i].is_sdu()) {
|
||||
subheaders[i].write_subheader(&ptr, i==last_sh);
|
||||
}
|
||||
}
|
||||
// Then for SDUs
|
||||
for (int i=0;i<nof_subheaders;i++) {
|
||||
if (subheaders[i].is_sdu()) {
|
||||
subheaders[i].write_subheader(&ptr, i==last_sh);
|
||||
}
|
||||
}
|
||||
// Write payloads in the same order
|
||||
for (int i=0;i<nof_subheaders;i++) {
|
||||
if (!subheaders[i].is_sdu()) {
|
||||
subheaders[i].write_payload(&ptr);
|
||||
}
|
||||
}
|
||||
for (int i=0;i<nof_subheaders;i++) {
|
||||
if (subheaders[i].is_sdu()) {
|
||||
subheaders[i].write_payload(&ptr);
|
||||
}
|
||||
}
|
||||
// Set paddint to zeros (if any)
|
||||
bzero(ptr, rem_len*sizeof(uint8_t)*8);
|
||||
|
||||
}
|
||||
|
||||
uint32_t sch_pdu::rem_size() {
|
||||
return rem_len;
|
||||
}
|
||||
|
||||
uint32_t sch_pdu::size()
|
||||
{
|
||||
return pdu_len - rem_len;
|
||||
}
|
||||
|
||||
uint32_t sch_pdu::size_plus_header_sdu(uint32_t nbytes)
|
||||
{
|
||||
if (nbytes < 128) {
|
||||
return nbytes + 2;
|
||||
} else {
|
||||
return nbytes + 3;
|
||||
}
|
||||
}
|
||||
bool sch_pdu::has_space_ce(uint32_t nbytes)
|
||||
{
|
||||
if (rem_len >= nbytes + 1) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool sch_pdu::has_space_sdu(uint32_t nbytes)
|
||||
{
|
||||
if (rem_len >= size_plus_header_sdu(nbytes)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool sch_pdu::update_space_ce(uint32_t nbytes)
|
||||
{
|
||||
if (has_space_ce(nbytes)) {
|
||||
rem_len -= nbytes + 1;
|
||||
}
|
||||
}
|
||||
bool sch_pdu::update_space_sdu(uint32_t nbytes)
|
||||
{
|
||||
if (has_space_sdu(nbytes)) {
|
||||
rem_len -= size_plus_header_sdu(nbytes);
|
||||
}
|
||||
}
|
||||
|
||||
void sch_subh::init()
|
||||
{
|
||||
lcid = 0;
|
||||
nof_bytes = 0;
|
||||
sdu_payload_ptr = NULL;
|
||||
bzero(ce_payload, sizeof(uint8_t) * MAX_CE_PAYLOAD_LEN);
|
||||
}
|
||||
|
||||
sch_subh::cetype sch_subh::ce_type()
|
||||
{
|
||||
if (lcid >= PHD_REPORT) {
|
||||
return (cetype) lcid;
|
||||
} else {
|
||||
return SDU;
|
||||
}
|
||||
}
|
||||
|
||||
void sch_subh::set_payload_size(uint32_t size) {
|
||||
nof_bytes = size;
|
||||
}
|
||||
|
||||
uint32_t sch_subh::size_plus_header() {
|
||||
if (is_sdu()) {
|
||||
return sch_pdu::size_plus_header_sdu(nof_bytes);
|
||||
} else {
|
||||
return nof_bytes + 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t sch_subh::sizeof_ce(uint32_t lcid, bool is_ul)
|
||||
{
|
||||
if (is_ul) {
|
||||
switch(lcid) {
|
||||
case PHD_REPORT:
|
||||
return 1;
|
||||
case C_RNTI:
|
||||
return 2;
|
||||
case TRUNC_BSR:
|
||||
return 1;
|
||||
case SHORT_BSR:
|
||||
return 1;
|
||||
case LONG_BSR:
|
||||
return 3;
|
||||
case PADDING:
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
switch(lcid) {
|
||||
case CON_RES_ID:
|
||||
return 6;
|
||||
case TA_CMD:
|
||||
return 1;
|
||||
case DRX_CMD:
|
||||
return 0;
|
||||
case PADDING:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool sch_subh::is_sdu()
|
||||
{
|
||||
return ce_type() == SDU;
|
||||
}
|
||||
uint16_t sch_subh::get_c_rnti()
|
||||
{
|
||||
uint8_t *ptr = ce_payload;
|
||||
uint16_t ret = (uint16_t) srslte_bit_unpack(&ptr, 16);
|
||||
return ret;
|
||||
}
|
||||
uint64_t sch_subh::get_con_res_id()
|
||||
{
|
||||
uint8_t *ptr = ce_payload;
|
||||
uint64_t ret = (uint64_t) srslte_bit_unpack_l(&ptr, 48);
|
||||
return ret;
|
||||
}
|
||||
uint8_t sch_subh::get_phd()
|
||||
{
|
||||
uint8_t *ptr = ce_payload;
|
||||
ptr += 2;
|
||||
uint8_t ret = (uint8_t) srslte_bit_unpack(&ptr, 6);
|
||||
return ret;
|
||||
}
|
||||
uint8_t sch_subh::get_ta_cmd()
|
||||
{
|
||||
uint8_t *ptr = ce_payload;
|
||||
ptr += 2;
|
||||
uint8_t ret = (uint8_t) srslte_bit_unpack(&ptr, 6);
|
||||
return ret;
|
||||
}
|
||||
uint32_t sch_subh::get_sdu_lcid()
|
||||
{
|
||||
return lcid;
|
||||
}
|
||||
uint32_t sch_subh::get_sdu_nbytes()
|
||||
{
|
||||
return nof_bytes;
|
||||
}
|
||||
uint8_t* sch_subh::get_sdu_ptr()
|
||||
{
|
||||
return sdu_payload_ptr;
|
||||
}
|
||||
void sch_subh::set_padding()
|
||||
{
|
||||
lcid = PADDING;
|
||||
}
|
||||
|
||||
bool sch_subh::set_bsr(uint32_t buff_size[4], sch_subh::cetype format)
|
||||
{
|
||||
uint32_t nonzero_lcg=0;
|
||||
for (int i=0;i<4;i++) {
|
||||
if (buff_size[i]) {
|
||||
nonzero_lcg=i;
|
||||
}
|
||||
}
|
||||
uint32_t ce_size = format==LONG_BSR?3:1;
|
||||
if (((sch_pdu*)parent)->has_space_ce(ce_size)) {
|
||||
uint8_t *ptr = ce_payload;
|
||||
if (format==LONG_BSR) {
|
||||
for (int i=0;i<4;i++) {
|
||||
srslte_bit_pack(buff_size_table(buff_size[i]), &ptr, 6);
|
||||
}
|
||||
} else {
|
||||
srslte_bit_pack(nonzero_lcg, &ptr, 2);
|
||||
srslte_bit_pack(buff_size_table(buff_size[nonzero_lcg]), &ptr, 6);
|
||||
}
|
||||
lcid = format;
|
||||
((sch_pdu*)parent)->update_space_ce(ce_size);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool sch_subh::set_c_rnti(uint16_t crnti)
|
||||
{
|
||||
if (((sch_pdu*)parent)->has_space_ce(2)) {
|
||||
|
||||
*((uint16_t*) ce_payload) = crnti;
|
||||
lcid = C_RNTI;
|
||||
uint8_t *ptr = ce_payload;
|
||||
srslte_bit_pack(crnti, &ptr, 16);
|
||||
((sch_pdu*)parent)->update_space_ce(2);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool sch_subh::set_con_res_id(uint64_t con_res_id)
|
||||
{
|
||||
if (((sch_pdu*)parent)->has_space_ce(6)) {
|
||||
uint8_t *ptr = ce_payload;
|
||||
srslte_bit_pack_l(con_res_id, &ptr, 48);
|
||||
lcid = CON_RES_ID;
|
||||
((sch_pdu*)parent)->update_space_ce(6);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool sch_subh::set_phd(uint8_t phd)
|
||||
{
|
||||
if (((sch_pdu*)parent)->has_space_ce(1)) {
|
||||
uint8_t *ptr = ce_payload;
|
||||
srslte_bit_pack(0, &ptr, 2);
|
||||
srslte_bit_pack(phd, &ptr, 6);
|
||||
lcid = PHD_REPORT;
|
||||
((sch_pdu*)parent)->update_space_ce(1);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool sch_subh::set_sdu(uint32_t lcid_, uint8_t* ptr, uint32_t nof_bytes_)
|
||||
{
|
||||
if (((sch_pdu*)parent)->has_space_sdu(nof_bytes_)) {
|
||||
sdu_payload_ptr = ptr;
|
||||
nof_bytes = nof_bytes_;
|
||||
lcid = lcid_;
|
||||
((sch_pdu*)parent)->update_space_sdu(nof_bytes_);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool sch_subh::set_ta_cmd(uint8_t ta_cmd)
|
||||
{
|
||||
if (((sch_pdu*)parent)->has_space_ce(1)) {
|
||||
uint8_t *ptr = ce_payload;
|
||||
srslte_bit_pack(0, &ptr, 2);
|
||||
srslte_bit_pack(ta_cmd, &ptr, 6);
|
||||
lcid = TA_CMD;
|
||||
((sch_pdu*)parent)->update_space_ce(1);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Section 6.2.1
|
||||
void sch_subh::write_subheader(uint8_t** ptr, bool is_last)
|
||||
{
|
||||
if (is_sdu()) {
|
||||
// MAC SDU: R/R/E/LCID/F/L subheader
|
||||
srslte_bit_pack(0, ptr, 2); // R, R
|
||||
srslte_bit_pack(is_last?0:1, ptr, 1); // E
|
||||
srslte_bit_pack(lcid, ptr, 5); // LCID
|
||||
|
||||
// 2nd and 3rd octet
|
||||
if (!is_last) {
|
||||
srslte_bit_pack(F_bit?1:0, ptr, 1); // F
|
||||
srslte_bit_pack(nof_bytes, ptr, nof_bytes<128?7:15); // L
|
||||
}
|
||||
} else {
|
||||
// MAC CE: R/R/E/LCID MAC Subheader
|
||||
srslte_bit_pack(0, ptr, 2); // R, R
|
||||
srslte_bit_pack(is_last?0:1, ptr, 1); // E
|
||||
srslte_bit_pack(lcid, ptr, 5); // LCID
|
||||
}
|
||||
}
|
||||
void sch_subh::write_payload(uint8_t** ptr)
|
||||
{
|
||||
uint8_t *src;
|
||||
if (is_sdu()) {
|
||||
src = sdu_payload_ptr;
|
||||
} else {
|
||||
src = ce_payload;
|
||||
}
|
||||
memcpy(*ptr, src, nof_bytes*8*sizeof(uint8_t));
|
||||
*ptr += nof_bytes*8;
|
||||
}
|
||||
bool sch_subh::read_subheader(uint8_t** ptr)
|
||||
{
|
||||
// Skip R
|
||||
*ptr += 2;
|
||||
bool e_bit = srslte_bit_unpack(ptr, 1)?true:false;
|
||||
lcid = srslte_bit_unpack(ptr, 5);
|
||||
if (is_sdu()) {
|
||||
if (e_bit) {
|
||||
F_bit = srslte_bit_unpack(ptr, 1)?true:false;
|
||||
nof_bytes = srslte_bit_unpack(ptr, F_bit?7:15);
|
||||
} else {
|
||||
nof_bytes = 0;
|
||||
F_bit = 0;
|
||||
}
|
||||
} else {
|
||||
nof_bytes = sizeof_ce(lcid, parent->is_ul());
|
||||
}
|
||||
return e_bit;
|
||||
}
|
||||
void sch_subh::read_payload(uint8_t** ptr)
|
||||
{
|
||||
if (is_sdu()) {
|
||||
sdu_payload_ptr = *ptr;
|
||||
} else {
|
||||
memcpy(ce_payload, *ptr, 8*nof_bytes*sizeof(uint8_t));
|
||||
}
|
||||
*ptr += nof_bytes*8;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void rar_pdu::fprint(FILE* stream)
|
||||
{
|
||||
fprintf(stream, "MAC PDU for RAR. ");
|
||||
if (has_backoff_indicator) {
|
||||
fprintf(stream, "Backoff Indicator %d. ", backoff_indicator);
|
||||
}
|
||||
pdu::fprint(stream);
|
||||
}
|
||||
|
||||
void rar_subh::fprint(FILE* stream)
|
||||
{
|
||||
fprintf(stream, "RAPID: %d, Temp C-RNTI: %d, TA: %d, UL Grant: ", preamble, temp_rnti, ta);
|
||||
srslte_vec_fprint_hex(stream, grant, 20);
|
||||
}
|
||||
|
||||
rar_pdu::rar_pdu(uint32_t max_rars_) : pdu(max_rars_)
|
||||
{
|
||||
backoff_indicator = 0;
|
||||
has_backoff_indicator = false;
|
||||
}
|
||||
uint8_t rar_pdu::get_backoff()
|
||||
{
|
||||
return backoff_indicator;
|
||||
}
|
||||
bool rar_pdu::has_backoff()
|
||||
{
|
||||
return has_backoff_indicator;
|
||||
}
|
||||
void rar_pdu::set_backoff(uint8_t bi)
|
||||
{
|
||||
has_backoff_indicator = true;
|
||||
backoff_indicator = bi;
|
||||
}
|
||||
|
||||
// Section 6.1.5
|
||||
bool rar_pdu::write_packet(uint8_t* ptr)
|
||||
{
|
||||
// Write Backoff Indicator, if any
|
||||
if (has_backoff_indicator) {
|
||||
if (nof_subheaders > 0) {
|
||||
srslte_bit_pack(1, &ptr, 1); // E
|
||||
srslte_bit_pack(0, &ptr, 1); // T
|
||||
srslte_bit_pack(0, &ptr, 2); // R, R
|
||||
srslte_bit_pack(backoff_indicator, &ptr, 4);
|
||||
}
|
||||
}
|
||||
// Write RAR subheaders
|
||||
for (int i=0;i<nof_subheaders;i++) {
|
||||
subheaders[i].write_subheader(&ptr, i==nof_subheaders-1);
|
||||
}
|
||||
// Write payload
|
||||
for (int i=0;i<nof_subheaders;i++) {
|
||||
subheaders[i].write_payload(&ptr);
|
||||
}
|
||||
// Set paddint to zeros (if any)
|
||||
bzero(ptr, rem_len*sizeof(uint8_t)*8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void rar_subh::init()
|
||||
{
|
||||
bzero(grant, sizeof(uint8_t) * RAR_GRANT_LEN);
|
||||
ta = 0;
|
||||
temp_rnti = 0;
|
||||
}
|
||||
uint32_t rar_subh::get_rapid()
|
||||
{
|
||||
return preamble;
|
||||
}
|
||||
void rar_subh::get_sched_grant(uint8_t grant_[RAR_GRANT_LEN])
|
||||
{
|
||||
memcpy(grant_, &grant, sizeof(uint8_t)*RAR_GRANT_LEN);
|
||||
}
|
||||
uint32_t rar_subh::get_ta_cmd()
|
||||
{
|
||||
return ta;
|
||||
}
|
||||
uint16_t rar_subh::get_temp_crnti()
|
||||
{
|
||||
return temp_rnti;
|
||||
}
|
||||
void rar_subh::set_rapid(uint32_t rapid)
|
||||
{
|
||||
preamble = rapid;
|
||||
}
|
||||
void rar_subh::set_sched_grant(uint8_t grant_[RAR_GRANT_LEN])
|
||||
{
|
||||
memcpy(&grant, grant_, sizeof(uint8_t)*RAR_GRANT_LEN);
|
||||
}
|
||||
void rar_subh::set_ta_cmd(uint32_t ta_)
|
||||
{
|
||||
ta = ta_;
|
||||
}
|
||||
void rar_subh::set_temp_crnti(uint16_t temp_rnti_)
|
||||
{
|
||||
temp_rnti = temp_rnti_;
|
||||
}
|
||||
// Section 6.2.2
|
||||
void rar_subh::write_subheader(uint8_t** ptr, bool is_last)
|
||||
{
|
||||
srslte_bit_pack(is_last?0:1, ptr, 1); // E
|
||||
srslte_bit_pack(1, ptr, 1); // T
|
||||
srslte_bit_pack(preamble, ptr, 6); // RAPID
|
||||
}
|
||||
// Section 6.2.3
|
||||
void rar_subh::write_payload(uint8_t** ptr)
|
||||
{
|
||||
srslte_bit_pack(0, ptr, 1); // R
|
||||
srslte_bit_pack(ta, ptr, 11); // Timing Adv Cmd
|
||||
memcpy(*ptr, grant, 20*sizeof(uint8_t)); // UL grant
|
||||
*ptr += 20;
|
||||
srslte_bit_pack(temp_rnti, ptr, 16); // Temp C-RNTI
|
||||
}
|
||||
void rar_subh::read_payload(uint8_t** ptr)
|
||||
{
|
||||
*ptr += 1; // R
|
||||
ta = srslte_bit_unpack(ptr, 11); // Timing Adv Cmd
|
||||
memcpy(grant, *ptr, 20*sizeof(uint8_t)); // UL Grant
|
||||
*ptr += 20;
|
||||
temp_rnti = srslte_bit_unpack(ptr, 16); // Temp C-RNTI
|
||||
}
|
||||
bool rar_subh::read_subheader(uint8_t** ptr)
|
||||
{
|
||||
bool e_bit = srslte_bit_unpack(ptr, 1); // E
|
||||
bool type = srslte_bit_unpack(ptr, 1); // T
|
||||
if (type) {
|
||||
preamble = srslte_bit_unpack(ptr, 6); // RAPID
|
||||
} else {
|
||||
// Read Backoff
|
||||
*ptr += 2; // R, R
|
||||
((rar_pdu*)parent)->set_backoff((uint8_t) srslte_bit_unpack(ptr, 4));
|
||||
}
|
||||
return e_bit;
|
||||
}
|
||||
|
||||
|
||||
// Table 6.1.3.1-1 Buffer size levels for BSR
|
||||
uint32_t btable[61] = {
|
||||
10, 12, 14, 17, 19, 22, 26, 31, 36, 42, 49, 57, 67, 78, 91, 107, 125, 146, 171, 200, 234, 274, 321, 376, 440, 515, 603, 706, 826, 967, 1132,
|
||||
1326, 1552, 1817, 2127, 2490, 2915, 3413, 3995, 4667, 5476, 6411, 7505, 8787, 10287, 12043, 14099, 16507, 19325, 22624, 26487, 31009, 36304,
|
||||
42502, 49759, 58255, 68201, 79846, 93479, 109439, 128125};
|
||||
|
||||
uint8_t sch_subh::buff_size_table(uint32_t buffer_size) {
|
||||
if (buffer_size == 0) {
|
||||
return 0;
|
||||
} else if (buffer_size > 150000) {
|
||||
return 63;
|
||||
} else {
|
||||
for (int i=0;i<61;i++) {
|
||||
if (buffer_size > btable[i]) {
|
||||
return 1+i;
|
||||
}
|
||||
}
|
||||
return 62;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,280 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "srsapps/ue/mac/proc_bsr.h"
|
||||
#include "srsapps/ue/mac/mac_params.h"
|
||||
#include "srsapps/ue/mac/mac.h"
|
||||
#include "srsapps/ue/mac/mux.h"
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
bsr_proc::bsr_proc()
|
||||
{
|
||||
initiated = false;
|
||||
timer_periodic = false;
|
||||
timer_retx = false;
|
||||
for (int i=0;i<MAX_LCID;i++) {
|
||||
lcg[i] = 0;
|
||||
priorities[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void bsr_proc::init(log* log_h_, timers *timers_db_, mac_params* params_db_, mac_io *mac_io_h_)
|
||||
{
|
||||
log_h = log_h;
|
||||
params_db = params_db_;
|
||||
mac_io_h = mac_io_h_;
|
||||
timers_db = timers_db_;
|
||||
initiated = true;
|
||||
}
|
||||
|
||||
void bsr_proc::reset()
|
||||
{
|
||||
triggered_bsr_type = NONE;
|
||||
}
|
||||
|
||||
/* Process Periodic BSR */
|
||||
void bsr_proc::timer_expired(uint32_t timer_id) {
|
||||
switch(timer_id) {
|
||||
case mac::BSR_TIMER_PERIODIC:
|
||||
if (triggered_bsr_type == NONE) {
|
||||
// Check condition 4 in Sec 5.4.5
|
||||
if (check_all_channels()) {
|
||||
triggered_bsr_type = PERIODIC;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case mac::BSR_TIMER_RETX:
|
||||
// Check condition 3 in Sec 5.4.5
|
||||
if (check_all_channels()) {
|
||||
triggered_bsr_type = REGULAR;
|
||||
sr_is_sent = false; // Enable reTx of SR
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Checks condition 1 for Regular BSR reporting */
|
||||
bool bsr_proc::check_highest_channel() {
|
||||
uint32_t lcg_with_data = 0;
|
||||
uint32_t pending_data = 0;
|
||||
uint32_t min_priority_group[4]={99, 99, 99, 99};
|
||||
bool trigger_bsr = true;
|
||||
|
||||
// Check if data arrived for a LCG
|
||||
for (uint32_t group=0;group<4;group++) {
|
||||
for (int i=0;i<mac_io::NOF_UL_LCH;i++) {
|
||||
if (lcg[group] == i) {
|
||||
if (priorities[i] < min_priority_group[group]) {
|
||||
min_priority_group[group] = priorities[i];
|
||||
}
|
||||
pending_data = mac_io_h->get(i)->pending_data();
|
||||
if (pending_data > 0) {
|
||||
lcg_with_data = group;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pending_data) {
|
||||
// If no data is available belonging to any of the logical channels belonging to any other LCG
|
||||
for (uint32_t group=0;group<4 && trigger_bsr;group++) {
|
||||
if (group != lcg_with_data) {
|
||||
for (int i=0;i<mac_io::NOF_UL_LCH && trigger_bsr;i++) {
|
||||
if (lcg[group] == i) {
|
||||
if (mac_io_h->get(i)->pending_data() && priorities[i] > min_priority_group[group]) {
|
||||
trigger_bsr=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return trigger_bsr;
|
||||
}
|
||||
|
||||
bool bsr_proc::check_all_channels() {
|
||||
bool ret = false;
|
||||
bzero(&pending_bsr, sizeof(bsr_t));
|
||||
for (int i=0;i<mac_io_h->NOF_UL_LCH;i++) {
|
||||
uint32_t n = mac_io_h->get(i)->pending_data();
|
||||
pending_bsr.buff_size[lcg[i]] += n;
|
||||
if (n > 0) {
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void bsr_proc::get_pending_bsr_format(uint32_t nof_padding_bytes) {
|
||||
uint32_t nof_lcg=0;
|
||||
for (int i=0;i<4;i++) {
|
||||
if (pending_bsr.buff_size[i] > 0) {
|
||||
nof_lcg++;
|
||||
}
|
||||
}
|
||||
if (triggered_bsr_type == PADDING) {
|
||||
if (nof_padding_bytes < 4) {
|
||||
// If space only for short
|
||||
if (nof_lcg > 1) {
|
||||
pending_bsr.format = TRUNC_BSR;
|
||||
uint32_t max_prio_ch = find_max_priority_lcid();
|
||||
for (int i=0;i<4;i++) {
|
||||
if (lcg[max_prio_ch] != i) {
|
||||
pending_bsr.buff_size[i] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pending_bsr.format = SHORT_BSR;
|
||||
}
|
||||
} else {
|
||||
// If space for long BSR
|
||||
pending_bsr.format = LONG_BSR;
|
||||
}
|
||||
} else {
|
||||
pending_bsr.format = SHORT_BSR;
|
||||
if (nof_lcg > 1) {
|
||||
pending_bsr.format = LONG_BSR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Checks if Regular BSR must be assembled, as defined in 5.4.5
|
||||
// Padding BSR is assembled when called by mux_unit when UL grant is received
|
||||
// Periodic BSR is triggered by the expiration of the timers
|
||||
void bsr_proc::step(uint32_t tti)
|
||||
{
|
||||
if (!initiated) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!timer_periodic) {
|
||||
if (params_db->get_param(mac_params::BSR_TIMER_PERIODIC)) {
|
||||
timer_periodic = true;
|
||||
timers_db->get(mac::BSR_TIMER_PERIODIC)->set(this, params_db->get_param(mac_params::BSR_TIMER_PERIODIC));
|
||||
}
|
||||
}
|
||||
|
||||
if (!timer_retx) {
|
||||
if (params_db->get_param(mac_params::BSR_TIMER_RETX)) {
|
||||
timer_retx = true;
|
||||
timers_db->get(mac::BSR_TIMER_RETX)->set(this, params_db->get_param(mac_params::BSR_TIMER_RETX));
|
||||
}
|
||||
}
|
||||
|
||||
// Check condition 1 in Sec 5.4.5
|
||||
if (triggered_bsr_type == NONE) {
|
||||
if (check_highest_channel()) {
|
||||
triggered_bsr_type = REGULAR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool bsr_proc::need_to_send_bsr_on_ul_grant(uint32_t nof_grant_bytes, uint32_t nof_padding_bytes, bsr_t *bsr)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if (triggered_bsr_type == NONE) {
|
||||
// If enough space for at least truncated BSR
|
||||
if (nof_padding_bytes >= 2) {
|
||||
// Check condition 2 in Sec 5.4.5
|
||||
if (check_all_channels()) {
|
||||
triggered_bsr_type = PADDING;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (triggered_bsr_type != NONE) {
|
||||
// If no more data is pending and there is no space for MAC CE
|
||||
uint32_t nof_pending_bytes = 0;
|
||||
for (int i=0;i<4;i++) {
|
||||
nof_pending_bytes += pending_bsr.buff_size[i];
|
||||
}
|
||||
// Do not include BSR CE if the UL grant can accomodate all pending data but is not sufficient
|
||||
// to additionally accomodate the BSR MAC CE plus its header
|
||||
uint32_t bsr_sz_plus_header = 1 + pending_bsr.format == LONG_BSR?3:1;
|
||||
if (nof_pending_bytes + bsr_sz_plus_header == nof_grant_bytes) {
|
||||
// if nof_pending_bytes + bsr_sz_plus_header > nof_grant_bytes, BSR has higher priority than data
|
||||
return false;
|
||||
}
|
||||
|
||||
get_pending_bsr_format(nof_padding_bytes);
|
||||
|
||||
// Instruct MUX unit to generate MAC CE
|
||||
ret = true;
|
||||
memcpy(bsr, &pending_bsr, sizeof(bsr_t));
|
||||
if (timer_periodic && pending_bsr.format != TRUNC_BSR) {
|
||||
timers_db->get(mac::BSR_TIMER_PERIODIC)->reset();
|
||||
timers_db->get(mac::BSR_TIMER_PERIODIC)->run();
|
||||
}
|
||||
// Cancel all triggered BSR
|
||||
triggered_bsr_type = NONE;
|
||||
}
|
||||
|
||||
// Restart or Start ReTX timer
|
||||
if (timer_retx) {
|
||||
timers_db->get(mac::BSR_TIMER_RETX)->reset();
|
||||
timers_db->get(mac::BSR_TIMER_RETX)->run();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool bsr_proc::need_to_send_sr() {
|
||||
if (!sr_is_sent && triggered_bsr_type == REGULAR) {
|
||||
sr_is_sent = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void bsr_proc::setup_lcg(uint32_t lcid, uint32_t new_lcg)
|
||||
{
|
||||
if (lcid < MAX_LCID && new_lcg < 4) {
|
||||
lcg[lcid] = new_lcg;
|
||||
}
|
||||
}
|
||||
|
||||
void bsr_proc::set_priority(uint32_t lcid, uint32_t priority) {
|
||||
if (lcid < MAX_LCID) {
|
||||
priorities[lcid] = priority;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t bsr_proc::find_max_priority_lcid() {
|
||||
uint32_t max_prio = 0, max_idx = 0;
|
||||
for (int i=0;i<MAX_LCID;i++) {
|
||||
if (priorities[i] > max_prio) {
|
||||
max_prio = priorities[i];
|
||||
max_idx = i;
|
||||
}
|
||||
}
|
||||
return max_idx;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,524 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "srsapps/ue/mac/mac_params.h"
|
||||
#include "srsapps/ue/mac/mac_io.h"
|
||||
#include "srsapps/ue/mac/proc_ra.h"
|
||||
#include "srsapps/ue/mac/mac.h"
|
||||
#include "srsapps/ue/mac/mux.h"
|
||||
|
||||
/* Random access procedure as specified in Section 5.1 of 36.321 */
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
// Table 7.2-1. Backoff Parameter values
|
||||
uint32_t backoff_table[16] = {0, 10, 20, 30, 40, 60, 80, 120, 160, 240, 320, 480, 960, 960, 960, 960};
|
||||
|
||||
// Table 7.6-1: DELTA_PREAMBLE values.
|
||||
int delta_preamble_db_table[5] = {0, 0, -3, -3, 8};
|
||||
|
||||
bool ra_proc::init(mac_params* params_db_, phy* phy_h_, srslte::log* log_h_, srslte::timers* timers_db_,
|
||||
mux* mux_unit_, demux* demux_unit_)
|
||||
{
|
||||
phy_h = phy_h_;
|
||||
log_h = log_h_;
|
||||
params_db = params_db_;
|
||||
timers_db = timers_db_;
|
||||
mux_unit = mux_unit_;
|
||||
demux_unit= demux_unit_;
|
||||
reset();
|
||||
}
|
||||
|
||||
void ra_proc::reset() {
|
||||
state = IDLE;
|
||||
}
|
||||
|
||||
void ra_proc::read_params() {
|
||||
|
||||
// Read initialization parameters
|
||||
configIndex = params_db->get_param(mac_params::RA_CONFIGINDEX);
|
||||
preambleIndex = params_db->get_param(mac_params::RA_PREAMBLEINDEX);
|
||||
maskIndex = params_db->get_param(mac_params::RA_MASKINDEX);
|
||||
nof_preambles = params_db->get_param(mac_params::RA_NOFPREAMBLES);
|
||||
if (!nof_preambles || nof_preambles > 64) {
|
||||
nof_preambles = 64;
|
||||
}
|
||||
nof_groupA_preambles = params_db->get_param(mac_params::RA_NOFGROUPAPREAMBLES);
|
||||
if (!nof_groupA_preambles) {
|
||||
nof_groupA_preambles = nof_preambles;
|
||||
}
|
||||
if (nof_groupA_preambles > nof_preambles) {
|
||||
nof_groupA_preambles = nof_preambles;
|
||||
}
|
||||
nof_groupB_preambles = nof_preambles - nof_groupA_preambles;
|
||||
if (nof_groupB_preambles) {
|
||||
messagePowerOffsetGroupB = params_db->get_param(mac_params::RA_MESSAGEPOWEROFFSETB);
|
||||
messageSizeGroupA = params_db->get_param(mac_params::RA_MESSAGESIZEA);
|
||||
Pcmax = params_db->get_param(mac_params::RA_PCMAX);
|
||||
deltaPreambleMsg3 = params_db->get_param(mac_params::RA_DELTAPREAMBLEMSG3);
|
||||
}
|
||||
responseWindowSize = params_db->get_param(mac_params::RA_RESPONSEWINDOW);
|
||||
powerRampingStep = params_db->get_param(mac_params::RA_POWERRAMPINGSTEP);
|
||||
preambleTransMax = params_db->get_param(mac_params::RA_PREAMBLETRANSMAX);
|
||||
iniReceivedTargetPower = params_db->get_param(mac_params::RA_INITRECEIVEDPOWER);
|
||||
contentionResolutionTimer = params_db->get_param(mac_params::RA_CONTENTIONTIMER);
|
||||
|
||||
delta_preamble_db = delta_preamble_db_table[configIndex%5];
|
||||
|
||||
if (contentionResolutionTimer > 0) {
|
||||
timers_db->get(mac::CONTENTION_TIMER)->set(this, contentionResolutionTimer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool ra_proc::in_progress()
|
||||
{
|
||||
return (state > IDLE && state != COMPLETION);
|
||||
}
|
||||
|
||||
bool ra_proc::is_successful() {
|
||||
return state == COMPLETION;
|
||||
}
|
||||
|
||||
bool ra_proc::is_response_error() {
|
||||
return state == RESPONSE_ERROR;
|
||||
}
|
||||
|
||||
bool ra_proc::is_contention_resolution() {
|
||||
return state == CONTENTION_RESOLUTION;
|
||||
}
|
||||
|
||||
bool ra_proc::is_error() {
|
||||
return state == RA_PROBLEM;
|
||||
}
|
||||
|
||||
uint32_t interval(uint32_t x1, uint32_t x2) {
|
||||
if (x1 > x2) {
|
||||
return x1-x2;
|
||||
} else {
|
||||
return 10240-x2+x1;
|
||||
}
|
||||
}
|
||||
|
||||
const char* state_str[11] = {"Idle",
|
||||
"RA Initializat.: ",
|
||||
"RA Initial.Wait: ",
|
||||
"RA ResSelection: ",
|
||||
"RA PreambleTx : ",
|
||||
"RA PreambleRx : ",
|
||||
"RA ResponseErr : ",
|
||||
"RA BackoffWait : ",
|
||||
"RA ContentResol: ",
|
||||
"RA Completed : ",
|
||||
"RA Problem : "};
|
||||
|
||||
#define rError(fmt, ...) Error("%s" fmt, state_str[state], ##__VA_ARGS__)
|
||||
#define rInfo(fmt, ...) Info("%s" fmt, state_str[state], ##__VA_ARGS__)
|
||||
#define rDebug(fmt, ...) Debug("%s" fmt, state_str[state], ##__VA_ARGS__)
|
||||
|
||||
|
||||
// Process Timing Advance Command as defined in Section 5.2
|
||||
void ra_proc::process_timeadv_cmd(uint32_t ta) {
|
||||
if (preambleIndex > 0) {
|
||||
// Preamble not selected by UE MAC
|
||||
phy_h->set_timeadv_rar(ta);
|
||||
timers_db->get(mac::TIME_ALIGNMENT)->reset();
|
||||
timers_db->get(mac::TIME_ALIGNMENT)->run();
|
||||
Info("Applying RAR TA CMD %d\n", ta);
|
||||
} else {
|
||||
// Preamble selected by UE MAC
|
||||
if (!timers_db->get(mac::TIME_ALIGNMENT)->is_running()) {
|
||||
phy_h->set_timeadv_rar(ta);
|
||||
timers_db->get(mac::TIME_ALIGNMENT)->run();
|
||||
Info("Applying RAR TA CMD %d\n", ta);
|
||||
} else {
|
||||
// Ignore TA CMD
|
||||
Warning("Ignoring RAR TA CMD because timeAlignmentTimer still running\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void* init_prach_thread(void *arg) {
|
||||
phy* phy_h = (phy*) arg;
|
||||
printf("thread initiating prach\n");
|
||||
if (phy_h->init_prach()) {
|
||||
return (void*) 0;
|
||||
} else {
|
||||
return (void*) -1;
|
||||
}
|
||||
}
|
||||
|
||||
void ra_proc::step_initialization() {
|
||||
read_params();
|
||||
pdcch_to_crnti_received = PDCCH_CRNTI_NOT_RECEIVED;
|
||||
transmitted_contention_id = 0;
|
||||
preambleTransmissionCounter = 1;
|
||||
first_rar_received = true;
|
||||
mux_unit->msg3_flush();
|
||||
backoff_param_ms = 0;
|
||||
if (pthread_create(&pt_init_prach, NULL, init_prach_thread, phy_h)) {
|
||||
perror("pthread_create");
|
||||
state = RA_PROBLEM;
|
||||
} else {
|
||||
state = INITIALIZATION_WAIT;
|
||||
}
|
||||
}
|
||||
|
||||
void ra_proc::step_initialization_wait() {
|
||||
int n = pthread_kill(pt_init_prach, 0);
|
||||
if (n) {
|
||||
void *status;
|
||||
pthread_join(pt_init_prach, &status);
|
||||
if (status) {
|
||||
rError("Initializing PRACH on PHY\n");
|
||||
state = RA_PROBLEM;
|
||||
} else {
|
||||
rInfo("PRACH init OK\n");
|
||||
state = RESOURCE_SELECTION;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ra_proc::step_resource_selection() {
|
||||
ra_group_t sel_group;
|
||||
if (preambleIndex > 0) {
|
||||
// Preamble is chosen by Higher layers (ie Network)
|
||||
sel_maskIndex = maskIndex;
|
||||
sel_preamble = (uint32_t) preambleIndex%nof_preambles;
|
||||
} else {
|
||||
// Preamble is chosen by MAC UE
|
||||
if (!msg3_transmitted) {
|
||||
if (nof_groupB_preambles > 0) { // Check also messageSizeGroupA and pathloss (Pcmax,deltaPreamble and powerOffset)
|
||||
sel_group = RA_GROUP_B;
|
||||
} else {
|
||||
sel_group = RA_GROUP_A;
|
||||
}
|
||||
last_msg3_group = sel_group;
|
||||
} else {
|
||||
sel_group = last_msg3_group;
|
||||
}
|
||||
if (sel_group == RA_GROUP_A) {
|
||||
sel_preamble = rand()%(nof_groupA_preambles-1);
|
||||
} else {
|
||||
sel_preamble = nof_groupA_preambles + rand()%(nof_groupB_preambles-1);
|
||||
}
|
||||
sel_maskIndex = 0;
|
||||
}
|
||||
rInfo("Selected preambleIndex=%d maskIndex=%d nof_GroupApreambles=%d\n", sel_preamble, sel_maskIndex,nof_groupA_preambles);
|
||||
state = PREAMBLE_TRANSMISSION;
|
||||
}
|
||||
|
||||
void ra_proc::step_preamble_transmission() {
|
||||
received_target_power_dbm = iniReceivedTargetPower +
|
||||
delta_preamble_db +
|
||||
(preambleTransmissionCounter-1)*powerRampingStep;
|
||||
|
||||
phy_h->send_prach(sel_preamble, sel_maskIndex - 1, received_target_power_dbm);
|
||||
rInfo("Selected received_target_power_dbm=%d dBm\n", received_target_power_dbm);
|
||||
state = RESPONSE_RECEPTION;
|
||||
}
|
||||
|
||||
void ra_proc::step_response_reception() {
|
||||
int ra_tti = phy_h->get_prach_transmitted_tti();
|
||||
if (ra_tti > 0) {
|
||||
|
||||
ra_rnti = 1+ra_tti%10; // f_id=0 for FDD
|
||||
dl_sched_grant rar_grant(ra_rnti);
|
||||
uint32_t interval_ra = interval(tti, ra_tti);
|
||||
|
||||
// Try to decode RAR only within the RA response window
|
||||
if (interval_ra >= 3 && interval_ra <= 3+responseWindowSize) {
|
||||
|
||||
// Get DL grant for RA-RNTI
|
||||
dl_buffer *dl_buffer = phy_h->get_dl_buffer(tti);
|
||||
if (dl_buffer->get_dl_grant(&rar_grant))
|
||||
{
|
||||
rInfo("DL grant found RA-RNTI=%d\n", ra_rnti);
|
||||
if (rar_grant.get_tbs() > MAX_RAR_PDU_LEN) {
|
||||
rError("RAR PDU exceeds local RAR PDU buffer (%d>%d)\n", rar_grant.get_tbs(), MAX_RAR_PDU_LEN);
|
||||
state = RESPONSE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
// Decode packet
|
||||
dl_buffer->reset_softbuffer();
|
||||
if (dl_buffer->decode_data(&rar_grant, rar_pdu_buffer)) {
|
||||
rDebug("RAR decoded successfully TBS=%d\n", rar_grant.get_tbs());
|
||||
|
||||
rar_pdu_msg.init(rar_grant.get_tbs()/8);
|
||||
rar_pdu_msg.parse_packet(rar_pdu_buffer);
|
||||
|
||||
// Set Backoff parameter
|
||||
if (rar_pdu_msg.has_backoff()) {
|
||||
backoff_param_ms = backoff_table[rar_pdu_msg.get_backoff()%16];
|
||||
} else {
|
||||
backoff_param_ms = 0;
|
||||
}
|
||||
|
||||
while(rar_pdu_msg.next()) {
|
||||
if (rar_pdu_msg.get()->get_rapid() == sel_preamble) {
|
||||
rInfo("Received RAPID=%d\n", sel_preamble);
|
||||
|
||||
process_timeadv_cmd(rar_pdu_msg.get()->get_ta_cmd());
|
||||
|
||||
// FIXME: Indicate received target power
|
||||
//phy_h->set_target_power_rar(iniReceivedTargetPower, (preambleTransmissionCounter-1)*powerRampingStep);
|
||||
|
||||
// Indicate grant to PHY layer. RAR grants have 6 sf delay (4 is the default delay)
|
||||
uint8_t grant[rar_subh::RAR_GRANT_LEN];
|
||||
rar_pdu_msg.get()->get_sched_grant(grant);
|
||||
phy_h->get_dl_buffer(tti+2)->set_rar_grant(grant);
|
||||
|
||||
if (preambleIndex > 0) {
|
||||
// Preamble selected by Network
|
||||
state = COMPLETION;
|
||||
} else {
|
||||
// Preamble selected by UE MAC
|
||||
params_db->set_param(mac_params::RNTI_TEMP, rar_pdu_msg.get()->get_temp_crnti());
|
||||
if (first_rar_received) {
|
||||
first_rar_received = false;
|
||||
|
||||
// Save transmitted C-RNTI (if any)
|
||||
transmitted_crnti = params_db->get_param(mac_params::RNTI_C);
|
||||
|
||||
// Save transmitted UE contention id, as defined by higher layers
|
||||
transmitted_contention_id = params_db->get_param(mac_params::CONTENTION_ID);
|
||||
params_db->set_param(mac_params::CONTENTION_ID, 0);
|
||||
|
||||
// If we have a C-RNTI, tell Mux unit to append C-RNTI CE if no CCCH SDU transmission
|
||||
if (transmitted_crnti) {
|
||||
mux_unit->append_crnti_ce_next_tx(transmitted_crnti);
|
||||
}
|
||||
|
||||
// Get TransportBlock size for the grant
|
||||
ul_sched_grant msg3_grant(sched_grant::RNTI_TYPE_TEMP, rar_pdu_msg.get()->get_temp_crnti());
|
||||
phy_h->get_dl_buffer(tti+2)->get_ul_grant(&msg3_grant);
|
||||
|
||||
// Move MAC PDU from Multiplexing and assembly unit to Msg3
|
||||
rInfo("Generating Msg3 for TBS=%d\n", msg3_grant.get_tbs());
|
||||
mux_unit->pdu_move_to_msg3(msg3_grant.get_tbs()); // 56 is the minimum grant provided
|
||||
}
|
||||
rDebug("Going to Contention Resolution state\n");
|
||||
state = CONTENTION_RESOLUTION;
|
||||
|
||||
// Start contention resolution timer
|
||||
timers_db->get(mac::CONTENTION_TIMER)->reset();
|
||||
timers_db->get(mac::CONTENTION_TIMER)->run();
|
||||
}
|
||||
} else {
|
||||
rDebug("Found RAR for preamble %d\n", rar_pdu_msg.get()->get_rapid());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
srslte_verbose = SRSLTE_VERBOSE_NONE;
|
||||
}
|
||||
if (interval_ra > 3+responseWindowSize && interval_ra < 10000) {
|
||||
rInfo("Timeout while trying to receive RAR\n");
|
||||
state = RESPONSE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ra_proc::step_response_error() {
|
||||
|
||||
preambleTransmissionCounter++;
|
||||
if (preambleTransmissionCounter == preambleTransMax + 1) {
|
||||
rError("Maximum number of transmissions reached (%d)\n", preambleTransMax);
|
||||
state = RA_PROBLEM;
|
||||
} else {
|
||||
backoff_interval_start = tti;
|
||||
if (backoff_param_ms) {
|
||||
backoff_inteval = rand()%backoff_param_ms;
|
||||
} else {
|
||||
backoff_inteval = 0;
|
||||
}
|
||||
if (backoff_inteval) {
|
||||
rInfo("Backoff wait interval %d\n", backoff_inteval);
|
||||
state = BACKOFF_WAIT;
|
||||
} else {
|
||||
rInfo("Transmitting inmediatly\n");
|
||||
state = RESOURCE_SELECTION;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ra_proc::step_backoff_wait() {
|
||||
if (interval(tti, backoff_interval_start) >= backoff_inteval) {
|
||||
state = RESOURCE_SELECTION;
|
||||
}
|
||||
}
|
||||
|
||||
void ra_proc::step_contention_resolution() {
|
||||
// If Msg3 has been sent
|
||||
if (mux_unit->msg3_is_transmitted()) {
|
||||
msg3_transmitted = true;
|
||||
if (pdcch_to_crnti_received != PDCCH_CRNTI_NOT_RECEIVED)
|
||||
{
|
||||
rInfo("PDCCH for C-RNTI received\n");
|
||||
// Random Access initiated by MAC itself or PDCCH order (transmission of MAC C-RNTI CE)
|
||||
if (start_mode == MAC_ORDER && pdcch_to_crnti_received == PDCCH_CRNTI_UL_GRANT ||
|
||||
start_mode == PDCCH_ORDER)
|
||||
{
|
||||
timers_db->get(mac::CONTENTION_TIMER)->stop();
|
||||
params_db->set_param(mac_params::RNTI_TEMP, 0);
|
||||
state = COMPLETION;
|
||||
}
|
||||
pdcch_to_crnti_received = PDCCH_CRNTI_NOT_RECEIVED;
|
||||
|
||||
} else if (demux_unit->is_temp_crnti_pending())
|
||||
{
|
||||
rInfo("MAC PDU with Temporal C-RNTI has been decoded\n");
|
||||
// Random Access initiated by RRC by the transmission of CCCH SDU
|
||||
if (demux_unit->is_contention_resolution_id_pending()) {
|
||||
rInfo("MAC PDU Contains Contention Resolution ID CE\n");
|
||||
// MAC PDU successfully decoded and contains MAC CE contention Id
|
||||
uint64_t rx_contention_id = demux_unit->get_contention_resolution_id();
|
||||
timers_db->get(mac::CONTENTION_TIMER)->stop();
|
||||
if (transmitted_contention_id == rx_contention_id) {
|
||||
rInfo("MAC PDU Contention Resolution ID matches the one transmitted in CCCH SDU\n");
|
||||
// UE Contention Resolution ID included in MAC CE matches the CCCH SDU transmitted in Msg3
|
||||
params_db->set_param(mac_params::RNTI_C, params_db->get_param(mac_params::RNTI_TEMP));
|
||||
|
||||
// finish the disassembly and demultiplexing of the MAC PDU
|
||||
demux_unit->demultiplex_pending_pdu();
|
||||
state = COMPLETION;
|
||||
} else {
|
||||
rInfo("Transmitted UE Contention Id differs from received Contention ID (0x%lx != 0x%lx)\n", transmitted_contention_id, rx_contention_id);
|
||||
// Discard MAC PDU
|
||||
demux_unit->discard_pending_pdu();
|
||||
|
||||
// Contention Resolution not successfully is like RAR not successful
|
||||
// FIXME: Need to flush Msg3 HARQ buffer. Why?
|
||||
state = RESPONSE_ERROR;
|
||||
}
|
||||
params_db->set_param(mac_params::RNTI_TEMP, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rDebug("Msg3 not yet transmitted\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ra_proc::step_completition() {
|
||||
params_db->set_param(mac_params::RA_PREAMBLEINDEX, 0);
|
||||
params_db->set_param(mac_params::RA_MASKINDEX, 0);
|
||||
mux_unit->msg3_flush();
|
||||
msg3_transmitted = false;
|
||||
}
|
||||
|
||||
void ra_proc::step(uint32_t tti_)
|
||||
{
|
||||
tti = tti_;
|
||||
if (is_running()) {
|
||||
switch(state) {
|
||||
case IDLE:
|
||||
break;
|
||||
case INITIALIZATION:
|
||||
step_initialization();
|
||||
break;
|
||||
case INITIALIZATION_WAIT:
|
||||
step_initialization_wait();
|
||||
break;
|
||||
case RESOURCE_SELECTION:
|
||||
step_resource_selection();
|
||||
break;
|
||||
case PREAMBLE_TRANSMISSION:
|
||||
step_preamble_transmission();
|
||||
break;
|
||||
case RESPONSE_RECEPTION:
|
||||
step_response_reception();
|
||||
break;
|
||||
case RESPONSE_ERROR:
|
||||
step_response_error();
|
||||
break;
|
||||
case BACKOFF_WAIT:
|
||||
step_backoff_wait();
|
||||
break;
|
||||
case CONTENTION_RESOLUTION:
|
||||
step_contention_resolution();
|
||||
break;
|
||||
case COMPLETION:
|
||||
step_completition();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ra_proc::start_mac_order()
|
||||
{
|
||||
if (state == IDLE || state == COMPLETION || state == RA_PROBLEM) {
|
||||
start_mode = MAC_ORDER;
|
||||
state = INITIALIZATION;
|
||||
run();
|
||||
}
|
||||
}
|
||||
|
||||
void ra_proc::start_pdcch_order()
|
||||
{
|
||||
if (state == IDLE || state == COMPLETION || state == RA_PROBLEM) {
|
||||
start_mode = PDCCH_ORDER;
|
||||
state = INITIALIZATION;
|
||||
run();
|
||||
}
|
||||
}
|
||||
|
||||
void ra_proc::start_rlc_order()
|
||||
{
|
||||
if (state == IDLE || state == COMPLETION || state == RA_PROBLEM) {
|
||||
start_mode = RLC_ORDER;
|
||||
state = INITIALIZATION;
|
||||
run();
|
||||
}
|
||||
}
|
||||
|
||||
// Contention Resolution Timer is expired (Section 5.1.5)
|
||||
void ra_proc::timer_expired(uint32_t timer_id)
|
||||
{
|
||||
rInfo("Contention Resolution Timer expired. Going to Response Error\n");
|
||||
params_db->set_param(mac_params::RNTI_TEMP, 0);
|
||||
state = RESPONSE_ERROR;
|
||||
}
|
||||
|
||||
void ra_proc::pdcch_to_crnti(bool is_uplink_grant) {
|
||||
if (is_uplink_grant) {
|
||||
pdcch_to_crnti_received = PDCCH_CRNTI_UL_GRANT;
|
||||
} else {
|
||||
pdcch_to_crnti_received = PDCCH_CRNTI_DL_GRANT;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,92 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "srsapps/ue/mac/proc_sr.h"
|
||||
#include "srsapps/ue/mac/mac_params.h"
|
||||
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
sr_proc::sr_proc() {
|
||||
initiated = false;
|
||||
}
|
||||
|
||||
void sr_proc::init(log* log_h_, mac_params* params_db_, phy* phy_h_)
|
||||
{
|
||||
log_h = log_h_;
|
||||
params_db = params_db_;
|
||||
phy_h = phy_h_;
|
||||
initiated = true;
|
||||
}
|
||||
|
||||
void sr_proc::reset()
|
||||
{
|
||||
is_pending_sr = false;
|
||||
phy_h->send_sr(false);
|
||||
}
|
||||
|
||||
void sr_proc::step(uint32_t tti)
|
||||
{
|
||||
if (initiated) {
|
||||
if (is_pending_sr) {
|
||||
if (sr_counter < dsr_transmax) {
|
||||
sr_counter++;
|
||||
phy_h->send_sr(true);
|
||||
} else {
|
||||
reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool sr_proc::need_random_access() {
|
||||
if (initiated) {
|
||||
if (sr_counter == dsr_transmax && dsr_transmax > 0 ||
|
||||
!params_db->get_param(mac_params::SR_PUCCH_CONFIGURED)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sr_proc::start()
|
||||
{
|
||||
if (initiated) {
|
||||
if (params_db->get_param(mac_params::SR_PUCCH_CONFIGURED)) {
|
||||
if (!is_pending_sr) {
|
||||
sr_counter = 0;
|
||||
dsr_transmax = params_db->get_param(mac_params::SR_TRANS_MAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,286 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "srsapps/ue/phy/phy.h"
|
||||
#include "srsapps/common/log.h"
|
||||
|
||||
#include "srsapps/ue/mac/mac_params.h"
|
||||
#include "srsapps/ue/mac/mac.h"
|
||||
#include "srsapps/ue/mac/ul_harq.h"
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
/***********************************************************
|
||||
*
|
||||
* HARQ ENTITY
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
bool ul_harq_entity::init(srslte_cell_t cell, mac_params *params_db_, log *log_h_, timers *timers_db_, mux *mux_unit_) {
|
||||
log_h = log_h_;
|
||||
mux_unit = mux_unit_;
|
||||
params_db = params_db_;
|
||||
timers_db = timers_db_;
|
||||
for (uint32_t i=0;i<NOF_HARQ_PROC;i++) {
|
||||
if (!proc[i].init(cell, this)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
uint32_t ul_harq_entity::pidof(uint32_t tti) {
|
||||
return (uint32_t) tti%NOF_HARQ_PROC;
|
||||
}
|
||||
void ul_harq_entity::reset() {
|
||||
for (uint32_t i=0;i<NOF_HARQ_PROC;i++) {
|
||||
proc[i].reset();
|
||||
}
|
||||
}
|
||||
void ul_harq_entity::reset_ndi() {
|
||||
for (uint32_t i=0;i<NOF_HARQ_PROC;i++) {
|
||||
proc[i].reset_ndi();
|
||||
}
|
||||
}
|
||||
bool ul_harq_entity::is_sps(uint32_t pid) {
|
||||
return false;
|
||||
}
|
||||
// Called with no UL grant
|
||||
void ul_harq_entity::run_tti(uint32_t tti, phy *phy_h) {
|
||||
run_tti(tti, NULL, phy_h);
|
||||
}
|
||||
|
||||
// Implements Section 5.4.2.1
|
||||
// Called with UL grant
|
||||
void ul_harq_entity::run_tti(uint32_t tti, ul_sched_grant *grant, phy *phy_h)
|
||||
{
|
||||
uint32_t tti_tx = (tti+4)%10240;
|
||||
uint32_t pid = pidof(tti_tx);
|
||||
|
||||
// Receive and route HARQ feedbacks
|
||||
int tti_harq = (int) tti - 4;
|
||||
if (tti_harq < 0) {
|
||||
tti_harq += 10240;
|
||||
}
|
||||
uint32_t pid_harq = pidof(tti_harq);
|
||||
if (proc[pid_harq].has_grant() && proc[pid_harq].last_tx_tti() <= tti_harq) {
|
||||
Info("Receiving HARQ feedback for PID=%d, TTI last TX %d, TTI harq %d\n", pid_harq, proc[pid_harq].last_tx_tti(), tti_harq);
|
||||
proc[pid_harq].set_harq_feedback(phy_h->get_dl_buffer(tti)->decode_ack(proc[pid_harq].get_grant()));
|
||||
}
|
||||
|
||||
if (grant) {
|
||||
if ((grant->is_temp_rnti() && grant->get_ndi() != proc[pid].get_ndi()) ||
|
||||
(grant->is_crnti() && !proc[pid].has_grant()) ||
|
||||
grant->is_from_rar())
|
||||
{
|
||||
// New transmission
|
||||
uint8_t* msg3_ptr = (uint8_t*) mux_unit->msg3_pop(grant->get_tbs());
|
||||
|
||||
// Uplink grant in a RAR
|
||||
if (grant->is_from_rar()) {
|
||||
if (msg3_ptr) {
|
||||
Info("Generating New Msg3 Transmission for PID=%d TTI=%d\n", pid, tti_tx);
|
||||
proc[pid].generate_new_tx(tti_tx, msg3_ptr, true, grant, phy_h->get_ul_buffer(tti_tx));
|
||||
mux_unit->msg3_transmitted();
|
||||
} else {
|
||||
Warning("UL RAR grant available but no Msg3 on buffer\n");
|
||||
}
|
||||
|
||||
// Normal UL grant
|
||||
} else {
|
||||
// Request a MAC PDU from the Multiplexing & Assemble Unit
|
||||
Info("Generating New Transmission for PID=%d TTI=%d\n", pid, tti_tx);
|
||||
uint8_t* mac_pdu = mux_unit->pdu_pop(grant->get_tbs());
|
||||
if (mac_pdu) {
|
||||
proc[pid].generate_new_tx(tti_tx, mac_pdu, false, grant, phy_h->get_ul_buffer(tti_tx));
|
||||
mux_unit->pdu_release();
|
||||
} else {
|
||||
Warning("Uplink grant with MAC PDU available in Multiplex Unit\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Adaptive Re-TX
|
||||
Info("Generating Adaptive Retransmission for PID=%d RV=%d\n", pid, proc[pid].get_rv());
|
||||
proc[pid].generate_retx(tti_tx, grant, phy_h->get_ul_buffer(tti_tx));
|
||||
}
|
||||
} else if (proc[pid].has_grant()) {
|
||||
// Non-Adaptive Re-Tx
|
||||
Info("Generating Non-adaptive Retransmission for PID=%d RV=%d\n", pid, proc[pid].get_rv());
|
||||
proc[pid].generate_retx(tti_tx, phy_h->get_ul_buffer(tti_tx));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************
|
||||
*
|
||||
* HARQ PROCESS
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
static int rv_of_irv[4] = {0, 2, 3, 1};
|
||||
static int irv_of_rv[4] = {0, 3, 1, 2};
|
||||
|
||||
ul_harq_entity::ul_harq_process::ul_harq_process() : cur_grant(0) {
|
||||
current_tx_nb = 0;
|
||||
current_irv = 0;
|
||||
is_initiated = false;
|
||||
is_grant_configured = false;
|
||||
tti_last_tx = 0;
|
||||
bzero(&cur_grant, sizeof(ul_sched_grant));
|
||||
}
|
||||
void ul_harq_entity::ul_harq_process::reset() {
|
||||
current_tx_nb = 0;
|
||||
current_irv = 0;
|
||||
tti_last_tx = 0;
|
||||
is_grant_configured = false;
|
||||
bzero(&cur_grant, sizeof(ul_sched_grant));
|
||||
if (is_initiated) {
|
||||
srslte_softbuffer_tx_reset(&softbuffer);
|
||||
}
|
||||
}
|
||||
bool ul_harq_entity::ul_harq_process::has_grant() {
|
||||
return is_grant_configured;
|
||||
}
|
||||
void ul_harq_entity::ul_harq_process::reset_ndi() {
|
||||
ndi = false;
|
||||
}
|
||||
bool ul_harq_entity::ul_harq_process::get_ndi()
|
||||
{
|
||||
return ndi;
|
||||
}
|
||||
|
||||
uint32_t ul_harq_entity::ul_harq_process::get_rv()
|
||||
{
|
||||
return rv_of_irv[current_irv%4];
|
||||
}
|
||||
|
||||
ul_sched_grant* ul_harq_entity::ul_harq_process::get_grant()
|
||||
{
|
||||
return &cur_grant;
|
||||
}
|
||||
|
||||
void ul_harq_entity::ul_harq_process::set_harq_feedback(bool ack) {
|
||||
harq_feedback = ack;
|
||||
// UL packet successfully delivered
|
||||
if (ack) {
|
||||
Info("HARQ = ACK for UL transmission. Discarting TB.\n");
|
||||
reset();
|
||||
} else {
|
||||
Info("HARQ = NACK for UL transmission\n");
|
||||
}
|
||||
}
|
||||
|
||||
bool ul_harq_entity::ul_harq_process::init(srslte_cell_t cell, ul_harq_entity *parent) {
|
||||
if (srslte_softbuffer_tx_init(&softbuffer, cell)) {
|
||||
fprintf(stderr, "Error initiating soft buffer\n");
|
||||
return false;
|
||||
} else {
|
||||
is_initiated = true;
|
||||
harq_entity = parent;
|
||||
log_h = harq_entity->log_h;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Retransmission with or w/o grant (Section 5.4.2.2)
|
||||
void ul_harq_entity::ul_harq_process::generate_retx(uint32_t tti_tx, ul_sched_grant* grant, ul_buffer* ul)
|
||||
{
|
||||
current_tx_nb++;
|
||||
if (grant) {
|
||||
// HARQ entity requests an adaptive transmission
|
||||
memcpy(&cur_grant, grant, sizeof(ul_sched_grant));
|
||||
current_irv = irv_of_rv[grant->get_rv()%4];
|
||||
harq_feedback = false;
|
||||
generate_tx(tti_tx, NULL, ul);
|
||||
} else {
|
||||
// HARQ entity requests a non-adaptive transmission
|
||||
if (!harq_feedback) {
|
||||
generate_tx(tti_tx, NULL, ul);
|
||||
}
|
||||
}
|
||||
|
||||
// On every Msg3 retransmission, restart mac-ContentionResolutionTimer as defined in Section 5.1.5
|
||||
if (is_msg3) {
|
||||
harq_entity->timers_db->get(mac::CONTENTION_TIMER)->reset();
|
||||
}
|
||||
}
|
||||
|
||||
void ul_harq_entity::ul_harq_process::generate_retx(uint32_t tti_tx, ul_buffer* ul)
|
||||
{
|
||||
generate_retx(tti_tx, NULL, ul);
|
||||
}
|
||||
|
||||
|
||||
// New transmission (Section 5.4.2.2)
|
||||
void ul_harq_entity::ul_harq_process::generate_new_tx(uint32_t tti_tx, uint8_t *pdu_payload, bool is_msg3_, ul_sched_grant* ul_grant, ul_buffer* ul)
|
||||
{
|
||||
if (ul_grant && pdu_payload) {
|
||||
srslte_softbuffer_tx_reset(&softbuffer);
|
||||
// Store the uplink grant
|
||||
memcpy(&cur_grant, ul_grant, sizeof(ul_sched_grant));
|
||||
harq_feedback = false;
|
||||
is_grant_configured = true;
|
||||
current_tx_nb = 0;
|
||||
current_irv = 0;
|
||||
is_msg3 = is_msg3_;
|
||||
generate_tx(tti_tx, pdu_payload, ul);
|
||||
}
|
||||
}
|
||||
|
||||
// Transmission of pending frame (Section 5.4.2.2)
|
||||
void ul_harq_entity::ul_harq_process::generate_tx(uint32_t tti_tx, uint8_t *pdu_payload, ul_buffer* ul)
|
||||
{
|
||||
cur_grant.set_rv(get_rv());
|
||||
ul->set_current_tx_nb(current_tx_nb);
|
||||
ul->generate_data(&cur_grant, &softbuffer, pdu_payload);
|
||||
|
||||
current_irv = (current_irv+1)%4;
|
||||
tti_last_tx = tti_tx;
|
||||
if (is_msg3) {
|
||||
if (current_tx_nb == harq_entity->params_db->get_param(mac_params::HARQ_MAXMSG3TX)) {
|
||||
Info("Maximum number of ReTX for Msg3 reached (%d). Discarting TB.\n", harq_entity->params_db->get_param(mac_params::HARQ_MAXMSG3TX));
|
||||
reset();
|
||||
}
|
||||
} else {
|
||||
if (current_tx_nb == harq_entity->params_db->get_param(mac_params::HARQ_MAXTX)) {
|
||||
Info("Maximum number of ReTX reached (%d). Discarting TB.\n", harq_entity->params_db->get_param(mac_params::HARQ_MAXTX));
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32_t ul_harq_entity::ul_harq_process::last_tx_tti()
|
||||
{
|
||||
return tti_last_tx;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
#
|
||||
# Copyright 2013-2015 The srsLTE Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution.
|
||||
#
|
||||
# This file is part of the srsLTE library.
|
||||
#
|
||||
# srsLTE is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# srsLTE is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Affero General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
FIND_PACKAGE(openLTE)
|
||||
|
||||
IF(UHD_FOUND AND OPENLTE_FOUND)
|
||||
INCLUDE_DIRECTORIES(${OPENLTE_INCLUDE_DIRS})
|
||||
ADD_EXECUTABLE(mac_test mac_test.cc)
|
||||
TARGET_LINK_LIBRARIES(mac_test srsapps_ue_mac srsapps_ue_phy srsapps_radio srslte ${OPENLTE_LIBRARIES} srslte_uhd)
|
||||
ENDIF(UHD_FOUND AND OPENLTE_FOUND)
|
@ -0,0 +1,359 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "liblte_rrc.h"
|
||||
#include "srsapps/radio/radio_uhd.h"
|
||||
#include "srsapps/ue/phy/phy.h"
|
||||
#include "srsapps/common/tti_sync_cv.h"
|
||||
#include "srsapps/common/log_stdout.h"
|
||||
#include "srsapps/ue/mac/mac.h"
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Program arguments processing
|
||||
***********************************************************************/
|
||||
typedef struct {
|
||||
float uhd_rx_freq;
|
||||
float uhd_tx_freq;
|
||||
float uhd_rx_gain;
|
||||
float uhd_tx_gain;
|
||||
int verbose;
|
||||
}prog_args_t;
|
||||
|
||||
void args_default(prog_args_t *args) {
|
||||
args->uhd_rx_freq = -1.0;
|
||||
args->uhd_tx_freq = -1.0;
|
||||
args->uhd_rx_gain = -1; // set to autogain
|
||||
args->uhd_tx_gain = -1;
|
||||
args->verbose = 0;
|
||||
}
|
||||
|
||||
void usage(prog_args_t *args, char *prog) {
|
||||
printf("Usage: %s [gv] -f rx_frequency (in Hz) -F tx_frequency (in Hz)\n", prog);
|
||||
printf("\t-g UHD RX gain [Default AGC]\n");
|
||||
printf("\t-G UHD TX gain [Default same as RX gain (AGC)]\n");
|
||||
printf("\t-v [increase verbosity, default none]\n");
|
||||
}
|
||||
|
||||
void parse_args(prog_args_t *args, int argc, char **argv) {
|
||||
int opt;
|
||||
args_default(args);
|
||||
while ((opt = getopt(argc, argv, "gGfFv")) != -1) {
|
||||
switch (opt) {
|
||||
case 'g':
|
||||
args->uhd_rx_gain = atof(argv[optind]);
|
||||
break;
|
||||
case 'G':
|
||||
args->uhd_tx_gain = atof(argv[optind]);
|
||||
break;
|
||||
case 'f':
|
||||
args->uhd_rx_freq = atof(argv[optind]);
|
||||
break;
|
||||
case 'F':
|
||||
args->uhd_tx_freq = atof(argv[optind]);
|
||||
break;
|
||||
case 'v':
|
||||
args->verbose++;
|
||||
break;
|
||||
default:
|
||||
usage(args, argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
if (args->uhd_rx_freq < 0 || args->uhd_tx_freq < 0) {
|
||||
usage(args, argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
// Determine SI messages scheduling as in 36.331 5.2.3 Acquisition of an SI message
|
||||
uint32_t sib_start_tti(uint32_t tti, uint32_t period, uint32_t x) {
|
||||
return (period*10*(1+tti/(period*10))+x)%10240; // the 1 means next opportunity
|
||||
}
|
||||
|
||||
void setup_mac_phy_sib2(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, srslte::ue::mac *mac, srslte::ue::phy *phy) {
|
||||
// RACH-CONFIGCOMMON
|
||||
if (sib2->rr_config_common_sib.rach_cnfg.preambles_group_a_cnfg.present) {
|
||||
mac->set_param(srslte::ue::mac_params::RA_NOFGROUPAPREAMBLES,
|
||||
liblte_rrc_message_size_group_a_num[sib2->rr_config_common_sib.rach_cnfg.preambles_group_a_cnfg.size_of_ra]);
|
||||
mac->set_param(srslte::ue::mac_params::RA_MESSAGESIZEA,
|
||||
liblte_rrc_message_size_group_a_num[sib2->rr_config_common_sib.rach_cnfg.preambles_group_a_cnfg.msg_size]);
|
||||
mac->set_param(srslte::ue::mac_params::RA_MESSAGEPOWEROFFSETB,
|
||||
liblte_rrc_message_power_offset_group_b_num[sib2->rr_config_common_sib.rach_cnfg.preambles_group_a_cnfg.msg_pwr_offset_group_b]);
|
||||
}
|
||||
mac->set_param(srslte::ue::mac_params::RA_NOFPREAMBLES,
|
||||
liblte_rrc_number_of_ra_preambles_num[sib2->rr_config_common_sib.rach_cnfg.num_ra_preambles]);
|
||||
mac->set_param(srslte::ue::mac_params::RA_POWERRAMPINGSTEP,
|
||||
liblte_rrc_power_ramping_step_num[sib2->rr_config_common_sib.rach_cnfg.pwr_ramping_step]);
|
||||
mac->set_param(srslte::ue::mac_params::RA_INITRECEIVEDPOWER,
|
||||
liblte_rrc_preamble_initial_received_target_power_num[sib2->rr_config_common_sib.rach_cnfg.preamble_init_rx_target_pwr]);
|
||||
mac->set_param(srslte::ue::mac_params::RA_PREAMBLETRANSMAX,
|
||||
liblte_rrc_preamble_trans_max_num[sib2->rr_config_common_sib.rach_cnfg.preamble_trans_max]);
|
||||
mac->set_param(srslte::ue::mac_params::RA_RESPONSEWINDOW,
|
||||
liblte_rrc_ra_response_window_size_num[sib2->rr_config_common_sib.rach_cnfg.ra_resp_win_size]);
|
||||
mac->set_param(srslte::ue::mac_params::RA_CONTENTIONTIMER,
|
||||
liblte_rrc_mac_contention_resolution_timer_num[sib2->rr_config_common_sib.rach_cnfg.mac_con_res_timer]);
|
||||
mac->set_param(srslte::ue::mac_params::HARQ_MAXMSG3TX,
|
||||
sib2->rr_config_common_sib.rach_cnfg.max_harq_msg3_tx);
|
||||
|
||||
printf("Set RACH ConfigCommon: NofPreambles=%d, ResponseWindow=%d, ContentionResolutionTimer=%d ms\n",
|
||||
liblte_rrc_number_of_ra_preambles_num[sib2->rr_config_common_sib.rach_cnfg.num_ra_preambles],
|
||||
liblte_rrc_ra_response_window_size_num[sib2->rr_config_common_sib.rach_cnfg.ra_resp_win_size],
|
||||
liblte_rrc_mac_contention_resolution_timer_num[sib2->rr_config_common_sib.rach_cnfg.mac_con_res_timer]);
|
||||
|
||||
// PDSCH ConfigCommon
|
||||
mac->set_param(srslte::ue::mac_params::PDSCH_RSPOWER,
|
||||
sib2->rr_config_common_sib.pdsch_cnfg.rs_power);
|
||||
mac->set_param(srslte::ue::mac_params::PDSCH_PB,
|
||||
sib2->rr_config_common_sib.pdsch_cnfg.p_b);
|
||||
|
||||
// PUSCH ConfigCommon
|
||||
phy->set_param(srslte::ue::phy_params::PUSCH_BETA, 10);
|
||||
phy->set_param(srslte::ue::phy_params::PUSCH_EN_64QAM,
|
||||
sib2->rr_config_common_sib.pusch_cnfg.enable_64_qam);
|
||||
phy->set_param(srslte::ue::phy_params::PUSCH_HOPPING_OFFSET,
|
||||
sib2->rr_config_common_sib.pusch_cnfg.pusch_hopping_offset);
|
||||
phy->set_param(srslte::ue::phy_params::PUSCH_HOPPING_N_SB,
|
||||
sib2->rr_config_common_sib.pusch_cnfg.n_sb);
|
||||
phy->set_param(srslte::ue::phy_params::PUSCH_HOPPING_INTRA_SF,
|
||||
sib2->rr_config_common_sib.pusch_cnfg.hopping_mode == LIBLTE_RRC_HOPPING_MODE_INTRA_AND_INTER_SUBFRAME?1:0);
|
||||
phy->set_param(srslte::ue::phy_params::PUSCH_RS_GROUP_HOPPING_EN,
|
||||
sib2->rr_config_common_sib.pusch_cnfg.ul_rs.group_hopping_enabled?1:0);
|
||||
phy->set_param(srslte::ue::phy_params::PUSCH_RS_SEQUENCE_HOPPING_EN,
|
||||
sib2->rr_config_common_sib.pusch_cnfg.ul_rs.sequence_hopping_enabled?1:0);
|
||||
phy->set_param(srslte::ue::phy_params::PUSCH_RS_CYCLIC_SHIFT,
|
||||
sib2->rr_config_common_sib.pusch_cnfg.ul_rs.cyclic_shift);
|
||||
phy->set_param(srslte::ue::phy_params::PUSCH_RS_GROUP_ASSIGNMENT,
|
||||
sib2->rr_config_common_sib.pusch_cnfg.ul_rs.group_assignment_pusch);
|
||||
|
||||
printf("Set PUSCH ConfigCommon: HopOffset=%d, RSGroup=%d, RSNcs=%d, N_sb=%d\n",
|
||||
sib2->rr_config_common_sib.pusch_cnfg.pusch_hopping_offset,
|
||||
sib2->rr_config_common_sib.pusch_cnfg.ul_rs.group_assignment_pusch,
|
||||
sib2->rr_config_common_sib.pusch_cnfg.ul_rs.cyclic_shift,
|
||||
sib2->rr_config_common_sib.pusch_cnfg.n_sb);
|
||||
|
||||
// PUCCH ConfigCommon
|
||||
phy->set_param(srslte::ue::phy_params::PUCCH_BETA, 10);
|
||||
phy->set_param(srslte::ue::phy_params::PUCCH_DELTA_SHIFT,
|
||||
liblte_rrc_delta_pucch_shift_num[sib2->rr_config_common_sib.pucch_cnfg.delta_pucch_shift]);
|
||||
phy->set_param(srslte::ue::phy_params::PUCCH_CYCLIC_SHIFT,
|
||||
sib2->rr_config_common_sib.pucch_cnfg.n_cs_an);
|
||||
phy->set_param(srslte::ue::phy_params::PUCCH_N_PUCCH_1,
|
||||
sib2->rr_config_common_sib.pucch_cnfg.n1_pucch_an);
|
||||
phy->set_param(srslte::ue::phy_params::PUCCH_N_RB_2,
|
||||
sib2->rr_config_common_sib.pucch_cnfg.n_rb_cqi);
|
||||
printf("Set PUCCH ConfigCommon: DeltaShift=%d, CyclicShift=%d, N1=%d, NRB=%d\n",
|
||||
liblte_rrc_delta_pucch_shift_num[sib2->rr_config_common_sib.pucch_cnfg.delta_pucch_shift],
|
||||
sib2->rr_config_common_sib.pucch_cnfg.n_cs_an,
|
||||
sib2->rr_config_common_sib.pucch_cnfg.n1_pucch_an,
|
||||
sib2->rr_config_common_sib.pucch_cnfg.n_rb_cqi);
|
||||
|
||||
|
||||
// PRACH Configcommon
|
||||
phy->set_param(srslte::ue::phy_params::PRACH_ROOT_SEQ_IDX,
|
||||
sib2->rr_config_common_sib.prach_cnfg.root_sequence_index);
|
||||
phy->set_param(srslte::ue::phy_params::PRACH_HIGH_SPEED_FLAG,
|
||||
sib2->rr_config_common_sib.prach_cnfg.prach_cnfg_info.high_speed_flag?1:0);
|
||||
phy->set_param(srslte::ue::phy_params::PRACH_FREQ_OFFSET,
|
||||
sib2->rr_config_common_sib.prach_cnfg.prach_cnfg_info.prach_freq_offset);
|
||||
phy->set_param(srslte::ue::phy_params::PRACH_ZC_CONFIG,
|
||||
sib2->rr_config_common_sib.prach_cnfg.prach_cnfg_info.zero_correlation_zone_config);
|
||||
phy->set_param(srslte::ue::phy_params::PRACH_CONFIG_INDEX,
|
||||
sib2->rr_config_common_sib.prach_cnfg.prach_cnfg_info.prach_config_index);
|
||||
|
||||
printf("Set PRACH ConfigCommon: SeqIdx=%d, HS=%d, FreqOffset=%d, ZC=%d, ConfigIndex=%d\n",
|
||||
sib2->rr_config_common_sib.prach_cnfg.root_sequence_index,
|
||||
sib2->rr_config_common_sib.prach_cnfg.prach_cnfg_info.high_speed_flag?1:0,
|
||||
sib2->rr_config_common_sib.prach_cnfg.prach_cnfg_info.prach_freq_offset,
|
||||
sib2->rr_config_common_sib.prach_cnfg.prach_cnfg_info.zero_correlation_zone_config,
|
||||
sib2->rr_config_common_sib.prach_cnfg.prach_cnfg_info.prach_config_index);
|
||||
}
|
||||
|
||||
void process_connsetup(LIBLTE_RRC_CONNECTION_SETUP_STRUCT *msg, srslte::ue::mac *mac, srslte::ue::phy *phy) {
|
||||
mac->set_param(srslte::ue::mac_params::HARQ_MAXTX,
|
||||
liblte_rrc_max_harq_tx_num[msg->rr_cnfg.mac_main_cnfg.explicit_value.ulsch_cnfg.max_harq_tx]);
|
||||
|
||||
phy->set_param(srslte::ue::phy_params::SR_PUCCH_RESINDEX,
|
||||
msg->rr_cnfg.phy_cnfg_ded.sched_request_cnfg.sr_pucch_resource_idx);
|
||||
phy->set_param(srslte::ue::phy_params::SR_CONFIG_INDEX,
|
||||
msg->rr_cnfg.phy_cnfg_ded.sched_request_cnfg.sr_cnfg_idx);
|
||||
|
||||
mac->set_param(srslte::ue::mac_params::SR_TRANS_MAX,
|
||||
liblte_rrc_dsr_trans_max_num[msg->rr_cnfg.phy_cnfg_ded.sched_request_cnfg.dsr_trans_max]);
|
||||
mac->set_param(srslte::ue::mac_params::SR_PUCCH_CONFIGURED, 1);
|
||||
|
||||
phy->set_param(srslte::ue::phy_params::UCI_I_OFFSET_ACK, msg->rr_cnfg.phy_cnfg_ded.pusch_cnfg_ded.beta_offset_ack_idx);
|
||||
phy->set_param(srslte::ue::phy_params::UCI_I_OFFSET_CQI, msg->rr_cnfg.phy_cnfg_ded.pusch_cnfg_ded.beta_offset_cqi_idx);
|
||||
phy->set_param(srslte::ue::phy_params::UCI_I_OFFSET_RI, msg->rr_cnfg.phy_cnfg_ded.pusch_cnfg_ded.beta_offset_ri_idx);
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
prog_args_t prog_args;
|
||||
srslte::ue::tti_sync_cv ttisync(10240);
|
||||
srslte::radio_uhd radio_uhd;
|
||||
srslte::ue::phy phy;
|
||||
srslte::ue::mac mac;
|
||||
srslte::log_stdout mac_log("MAC"), phy_log("PHY");
|
||||
|
||||
parse_args(&prog_args, argc, argv);
|
||||
|
||||
switch (prog_args.verbose) {
|
||||
case 1:
|
||||
mac_log.set_level_info();
|
||||
phy_log.set_level_info();
|
||||
break;
|
||||
case 2:
|
||||
mac_log.set_level_debug();
|
||||
phy_log.set_level_debug();
|
||||
break;
|
||||
}
|
||||
|
||||
// Init Radio and PHY
|
||||
if (prog_args.uhd_rx_gain > 0 && prog_args.uhd_tx_gain > 0) {
|
||||
radio_uhd.init();
|
||||
radio_uhd.set_rx_gain(prog_args.uhd_rx_gain);
|
||||
radio_uhd.set_tx_gain(prog_args.uhd_tx_gain);
|
||||
phy.init(&radio_uhd, &ttisync, &phy_log);
|
||||
} else {
|
||||
radio_uhd.init_agc();
|
||||
radio_uhd.set_tx_rx_gain_offset(-10);
|
||||
phy.init_agc(&radio_uhd, &ttisync, &phy_log);
|
||||
}
|
||||
// Init MAC
|
||||
mac.init(&phy, &ttisync, &mac_log);
|
||||
|
||||
// Set RX freq
|
||||
radio_uhd.set_rx_freq(prog_args.uhd_rx_freq);
|
||||
radio_uhd.set_tx_freq(prog_args.uhd_tx_freq);
|
||||
|
||||
LIBLTE_BIT_MSG_STRUCT bit_msg;
|
||||
LIBLTE_RRC_MIB_STRUCT bch_msg;
|
||||
LIBLTE_RRC_BCCH_DLSCH_MSG_STRUCT dlsch_msg;
|
||||
LIBLTE_RRC_UL_CCCH_MSG_STRUCT ul_ccch_msg;
|
||||
LIBLTE_RRC_DL_CCCH_MSG_STRUCT dl_ccch_msg;
|
||||
|
||||
uint32_t si_window_len, sib2_period;
|
||||
int tti;
|
||||
enum {START, SIB1, SIB2, CONNECT} state = START;
|
||||
int n;
|
||||
|
||||
while(1) {
|
||||
switch(state) {
|
||||
case START:
|
||||
n = mac.recv_bcch_sdu(bit_msg.msg, LIBLTE_MAX_MSG_SIZE);
|
||||
if (n > 0) {
|
||||
bit_msg.N_bits = n;
|
||||
liblte_rrc_unpack_bcch_bch_msg(&bit_msg, &bch_msg);
|
||||
printf("MIB received %d bytes, BW=%s\n", n, liblte_rrc_dl_bandwidth_text[bch_msg.dl_bw]);
|
||||
state = SIB1;
|
||||
}
|
||||
break;
|
||||
case SIB1:
|
||||
n = mac.recv_bcch_sdu(bit_msg.msg, LIBLTE_MAX_MSG_SIZE);
|
||||
if (n > 0) {
|
||||
bit_msg.N_bits = n;
|
||||
liblte_rrc_unpack_bcch_dlsch_msg(&bit_msg, &dlsch_msg);
|
||||
si_window_len = liblte_rrc_si_window_length_num[dlsch_msg.sibs[0].sib.sib1.si_window_length];
|
||||
sib2_period = liblte_rrc_si_periodicity_num[dlsch_msg.sibs[0].sib.sib1.sched_info[0].si_periodicity];
|
||||
printf("SIB1 received %d bytes, CellID=%d, si_window=%d, sib2_period=%d\n",
|
||||
n/8, dlsch_msg.sibs[0].sib.sib1.cell_id&0xfff, si_window_len, sib2_period);
|
||||
state = SIB2;
|
||||
} else {
|
||||
tti = mac.get_tti();
|
||||
mac.set_param(srslte::ue::mac_params::BCCH_SI_WINDOW_ST, sib_start_tti(tti, 2, 5));
|
||||
mac.set_param(srslte::ue::mac_params::BCCH_SI_WINDOW_LEN, 1);
|
||||
}
|
||||
break;
|
||||
case SIB2:
|
||||
n = mac.recv_bcch_sdu(bit_msg.msg, LIBLTE_MAX_MSG_SIZE);
|
||||
if (n > 0) {
|
||||
// Process SIB2
|
||||
bit_msg.N_bits = n;
|
||||
liblte_rrc_unpack_bcch_dlsch_msg(&bit_msg, &dlsch_msg);
|
||||
printf("SIB2 received %d bytes\n", n/8);
|
||||
setup_mac_phy_sib2(&dlsch_msg.sibs[0].sib.sib2, &mac, &phy);
|
||||
|
||||
// Prepare ConnectionRequest packet
|
||||
ul_ccch_msg.msg_type = LIBLTE_RRC_UL_CCCH_MSG_TYPE_RRC_CON_REQ;
|
||||
ul_ccch_msg.msg.rrc_con_req.ue_id_type = LIBLTE_RRC_CON_REQ_UE_ID_TYPE_RANDOM_VALUE;
|
||||
ul_ccch_msg.msg.rrc_con_req.ue_id.random = 1000;
|
||||
ul_ccch_msg.msg.rrc_con_req.cause = LIBLTE_RRC_CON_REQ_EST_CAUSE_MO_DATA;
|
||||
liblte_rrc_pack_ul_ccch_msg(&ul_ccch_msg, &bit_msg);
|
||||
|
||||
uint64_t uecri=0;
|
||||
uint8_t *ue_cri_ptr = (uint8_t*) &uecri;
|
||||
uint32_t nbytes = bit_msg.N_bits/8;
|
||||
uint8_t *ptr = bit_msg.msg;
|
||||
for (int i=0;i<nbytes;i++) {
|
||||
ue_cri_ptr[nbytes-i-1] = (uint8_t) srslte_bit_unpack(&ptr, 8);
|
||||
}
|
||||
mac.set_param(srslte::ue::mac_params::CONTENTION_ID, uecri);
|
||||
|
||||
// Send ConnectionRequest Packet
|
||||
printf("Send ConnectionRequest %d bytes\n", nbytes);
|
||||
mac.send_ccch_sdu(bit_msg.msg, bit_msg.N_bits);
|
||||
state = CONNECT;
|
||||
} else {
|
||||
tti = mac.get_tti();
|
||||
mac.set_param(srslte::ue::mac_params::BCCH_SI_WINDOW_ST, sib_start_tti(tti, sib2_period, 0));
|
||||
mac.set_param(srslte::ue::mac_params::BCCH_SI_WINDOW_LEN, si_window_len);
|
||||
}
|
||||
break;
|
||||
case CONNECT:
|
||||
// Waint for Connection Setup
|
||||
n = mac.recv_ccch_sdu(bit_msg.msg, LIBLTE_MAX_MSG_SIZE);
|
||||
if (n > 0) {
|
||||
printf("ConnSetup received %d bytes\n", n/8);
|
||||
bit_msg.N_bits = n;
|
||||
liblte_rrc_unpack_dl_ccch_msg(&bit_msg, &dl_ccch_msg);
|
||||
printf("Response: %s\n", liblte_rrc_dl_ccch_msg_type_text[dl_ccch_msg.msg_type]);
|
||||
switch (dl_ccch_msg.msg_type) {
|
||||
case LIBLTE_RRC_DL_CCCH_MSG_TYPE_RRC_CON_SETUP:
|
||||
// Process ConnectionSetup
|
||||
process_connsetup(&dl_ccch_msg.msg.rrc_con_setup, &mac, &phy);
|
||||
break;
|
||||
case LIBLTE_RRC_DL_CCCH_MSG_TYPE_RRC_CON_REJ:
|
||||
mac.set_param(srslte::ue::mac_params::RNTI_C, 0);
|
||||
break;
|
||||
}
|
||||
// exit(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
usleep(10000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,38 @@
|
||||
#
|
||||
# Copyright 2013-2015 The srsLTE Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution.
|
||||
#
|
||||
# This file is part of the srsLTE library.
|
||||
#
|
||||
# srsLTE is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# srsLTE is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Affero General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
INSTALL(DIRECTORY include/
|
||||
DESTINATION "${INCLUDE_DIR}"
|
||||
FILES_MATCHING PATTERN "*.h"
|
||||
PATTERN ".svn" EXCLUDE
|
||||
)
|
||||
|
||||
FILE(GLOB SOURCES "src/*.cc")
|
||||
ADD_LIBRARY(srsapps_ue_phy SHARED ${SOURCES})
|
||||
TARGET_LINK_LIBRARIES(srsapps_ue_phy srsapps_common)
|
||||
INSTALL(TARGETS srsapps_ue_phy DESTINATION ${LIBRARY_DIR})
|
||||
SRSLTE_SET_PIC(srsapps_ue_phy)
|
||||
|
||||
FILE(GLOB HEADERS_ALL "include/srsapps/ue/phy/*.h")
|
||||
ADD_CUSTOM_TARGET (add_ue_phy_headers SOURCES ${HEADERS_ALL})
|
||||
|
||||
ADD_SUBDIRECTORY(test)
|
||||
|
@ -0,0 +1,97 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "srslte/srslte.h"
|
||||
#include "srsapps/common/queue.h"
|
||||
|
||||
#ifndef UESCHEDGRANT_H
|
||||
#define UESCHEDGRANT_H
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
/* Uplink/Downlink scheduling grant generated by a successfully decoded PDCCH */
|
||||
class sched_grant {
|
||||
public:
|
||||
typedef enum {
|
||||
RNTI_TYPE_NOTDEFINED = 0,
|
||||
RNTI_TYPE_CRNTI,
|
||||
RNTI_TYPE_RA,
|
||||
RNTI_TYPE_SPS,
|
||||
RNTI_TYPE_TEMP,
|
||||
RNTI_TYPE_SIRNTI,
|
||||
RNTI_TYPE_PRNTI,
|
||||
RNTI_TYPE_TPC_PUSCH,
|
||||
RNTI_TYPE_TPC_PUCCH
|
||||
} rnti_type_t;
|
||||
|
||||
sched_grant(uint16_t rnti_) {
|
||||
rnti = rnti_;
|
||||
rnti_type = RNTI_TYPE_NOTDEFINED;
|
||||
}
|
||||
sched_grant(rnti_type_t rnti_type_, uint16_t rnti_) {
|
||||
rnti = rnti_;
|
||||
rnti_type = rnti_type_;
|
||||
}
|
||||
uint16_t get_rnti() {
|
||||
return rnti;
|
||||
}
|
||||
bool is_temp_rnti() {
|
||||
return rnti_type == RNTI_TYPE_TEMP;
|
||||
}
|
||||
bool is_crnti() {
|
||||
return rnti_type == RNTI_TYPE_CRNTI;
|
||||
}
|
||||
bool is_ra_rnti() {
|
||||
return rnti_type == RNTI_TYPE_RA;
|
||||
}
|
||||
bool is_SPS_rnti() {
|
||||
return rnti_type == RNTI_TYPE_SPS;
|
||||
}
|
||||
bool is_sys_rnti() {
|
||||
return (rnti_type == RNTI_TYPE_SIRNTI || rnti_type == RNTI_TYPE_PRNTI);
|
||||
}
|
||||
bool is_tpc_rnti() {
|
||||
return (rnti_type == RNTI_TYPE_TPC_PUSCH || rnti_type == RNTI_TYPE_TPC_PUCCH);
|
||||
}
|
||||
virtual uint32_t get_rv() = 0;
|
||||
virtual void set_rv(uint32_t rv) = 0;
|
||||
virtual bool get_ndi() = 0;
|
||||
virtual void set_ndi(bool value) = 0;
|
||||
virtual bool is_sps_release() = 0;
|
||||
virtual uint32_t get_tbs() = 0;
|
||||
protected:
|
||||
uint16_t rnti;
|
||||
rnti_type_t rnti_type;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,30 +1,29 @@
|
||||
#
|
||||
# Copyright 2012-2013 The srsLTE Developers. See the
|
||||
# Copyright 2013-2015 The srsLTE Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution.
|
||||
#
|
||||
# This file is part of the srsLTE library.
|
||||
#
|
||||
# srsLTE is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# srsLTE is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Lesser General Public License can be found in
|
||||
# A copy of the GNU Affero General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
|
||||
LIST(FIND OPTIONAL_LIBS cuhd CUHD_FIND)
|
||||
IF(${CUHD_FIND} GREATER -1)
|
||||
IF(UHD_FOUND)
|
||||
ADD_EXECUTABLE(ue_itf_test_sib1 ue_itf_test_sib1.cc)
|
||||
TARGET_LINK_LIBRARIES(ue_itf_test_sib1 srslte++ cuhd)
|
||||
TARGET_LINK_LIBRARIES(ue_itf_test_sib1 srsapps_ue_phy srsapps_radio srslte srslte_uhd)
|
||||
|
||||
ADD_EXECUTABLE(ue_itf_test_prach ue_itf_test_prach.cc)
|
||||
TARGET_LINK_LIBRARIES(ue_itf_test_prach srslte++ cuhd)
|
||||
ENDIF(${CUHD_FIND} GREATER -1)
|
||||
TARGET_LINK_LIBRARIES(ue_itf_test_prach srsapps_ue_phy srsapps_radio srslte srslte_uhd)
|
||||
ENDIF(UHD_FOUND)
|
@ -1,52 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "srslte/srslte.h"
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
uint32_t max_frames_pbch; // maximum number of 5ms frames to capture for MIB decoding
|
||||
uint32_t max_frames_pss; // maximum number of 5ms frames to capture for PSS correlation
|
||||
float threshold; // early-stops cell detection if mean PSR is above this value
|
||||
float init_agc; // 0 or negative to disable AGC
|
||||
}cell_search_cfg_t;
|
||||
|
||||
int cuhd_mib_decoder(void *uhd,
|
||||
cell_search_cfg_t *config,
|
||||
srslte_cell_t *cell);
|
||||
|
||||
int cuhd_cell_search(void *uhd,
|
||||
cell_search_cfg_t *config,
|
||||
int force_N_id_2,
|
||||
srslte_cell_t *cell);
|
||||
|
||||
int cuhd_search_and_decode_mib(void *uhd,
|
||||
cell_search_cfg_t *config,
|
||||
int force_N_id_2,
|
||||
srslte_cell_t *cell);
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue