diff --git a/openair2/LAYER2/RLC/AM/COPYING b/openair2/LAYER2/RLC/AM/COPYING deleted file mode 100644 index 94a9ed024d3859793618152ea559a168bbcbb5e2..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 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. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is 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. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - 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. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - 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 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. Use with the GNU Affero General Public License. - - 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 Affero 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 special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU 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 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 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 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 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 General Public License for more details. - - You should have received a copy of the GNU 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 the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - <program> Copyright (C) <year> <name of author> - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - 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 GPL, see -<http://www.gnu.org/licenses/>. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/openair2/LAYER2/RLC/AM/rlc_am.c b/openair2/LAYER2/RLC/AM/rlc_am.c deleted file mode 100755 index bea1cfff8d968ec0c6acdc067b35266eb05d9f1f..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am.c +++ /dev/null @@ -1,604 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am.c - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - ***************************************************************************/ -#include "rtos_header.h" -#include "platform_types.h" -#include "platform_constants.h" -//----------------------------------------------------------------------------- -#include "rlc_am_entity.h" -#include "rlc_am_mux_proto_extern.h" -#include "rlc_am_segment_proto_extern.h" -#include "rlc_am_receiver_proto_extern.h" -#include "rlc_am_demux_proto_extern.h" -#include "rlc_am_reset_proto_extern.h" -#include "rlc_am_status_proto_extern.h" -#include "rlc_am_errno.h" -#include "umts_timer_proto_extern.h" -#include "rlc_am_discard_rx_proto_extern.h" -#include "rlc_am_discard_tx_proto_extern.h" -#include "rlc_am_discard_notif_proto_extern.h" -#include "mac_primitives.h" -#include "rlc_primitives.h" -#include "rlc_am_control_primitives_proto_extern.h" -#include "rlc_am_util_proto_extern.h" -#include "list.h" -#include "LAYER2/MAC/extern.h" -//#define DEBUG_RLC_AM_DATA_REQUEST -//#define DEBUG_RLC_AM_TX -//#define DEBUG_RLC_AM_RX -//#define DEBUG_RLC_AM_BO -//----------------------------------------------------------------------------- -void display_protocol_vars_rlc_am (struct rlc_am_entity *rlcP); -uint32_t rlc_am_get_buffer_occupancy_in_pdus_for_ch1 (struct rlc_am_entity *rlcP); -uint32_t rlc_am_get_buffer_occupancy_in_pdus_for_ch2 (struct rlc_am_entity *rlcP); -void *rlc_am_tx (void *argP); -void rlc_am_rx (void *argP, struct mac_data_ind data_indP); -//----------------------------------------------------------------------------- -uint32_t -rlc_am_get_buffer_occupancy_in_bytes_ch1 (struct rlc_am_entity *rlcP) -{ - //----------------------------------------------------------------------------- - uint32_t sum = 0; - - if (rlcP->buffer_occupancy > 0) { - sum += (rlcP->pdus_to_mac_layer_ch1.nb_elements * rlcP->pdu_size); - sum += (rlcP->buffer_occupancy_retransmission_buffer * rlcP->pdu_size); - sum += rlcP->control.nb_elements * rlcP->pdu_size; // TEST LG + HA 23/10/2008 - sum += rlcP->buffer_occupancy; // approximation because of headers of pdus - } else { - if ((rlcP->li_one_byte_short_to_add_in_next_pdu) || - (rlcP->li_exactly_filled_to_add_in_next_pdu)) { - // WARNING LG WE ASSUME TRANSPORT BLOCKS ARE < 125 bytes - sum = rlcP->pdu_size; // 4 bytes; // so this is the exact size of the next TB to be sent (SN + 2LIs) - } - } - - -#ifdef DEBUG_RLC_AM_BO - msg ("[RLC_AM][RB %d] DTCH BO: %d bytes \n", rlcP->rb_id,sum); -#endif - return sum; -} - -//----------------------------------------------------------------------------- -uint32_t -rlc_am_get_buffer_occupancy_in_bytes_ch2 (struct rlc_am_entity * rlcP) -{ - //----------------------------------------------------------------------------- -#ifdef DEBUG_RLC_AM_BO - msg ("[RLC_AM][RB %d] DCCH BO: CONTROL %d DCCH %d\n", rlcP->rb_id, rlcP->control.nb_elements * rlcP->pdu_size, - rlcP->pdus_to_mac_layer_ch2.nb_elements * rlcP->pdu_size); -#endif - return rlcP->control.nb_elements * rlcP->pdu_size + rlcP->pdus_to_mac_layer_ch2.nb_elements * rlcP->pdu_size; -} - -//----------------------------------------------------------------------------- -uint32_t -rlc_am_get_buffer_occupancy_in_pdus_ch1 (struct rlc_am_entity * rlcP) -{ - //----------------------------------------------------------------------------- - uint32_t sum = 0; - - sum += rlcP->pdus_to_mac_layer_ch1.nb_elements; - sum += rlcP->buffer_occupancy_retransmission_buffer; - sum += rlcP->control.nb_elements; // TEST LG + HA 23/10/2008 - sum += (rlcP->buffer_occupancy / (rlcP->pdu_size - 2)); // minus 2 = size min for pdu header - -#ifdef DEBUG_RLC_AM_BO - msg ("[RLC_AM][RB %d] BO : CH1 %d blocks \n", rlcP->rb_id, rlcP->pdus_to_mac_layer_ch1.nb_elements); - msg ("[RLC_AM][RB %d] BO : RETRANS BUFFER %d blocks \n", rlcP->rb_id, rlcP->buffer_occupancy_retransmission_buffer); - msg ("[RLC_AM][RB %d] BO : BUFFER SDU %d blocks \n", rlcP->rb_id, rlcP->buffer_occupancy / (rlcP->pdu_size - 2)); -#endif - return sum; -} -//----------------------------------------------------------------------------- -uint32_t -rlc_am_get_buffer_occupancy_in_pdus_ch2 (struct rlc_am_entity * rlcP) -{ - //----------------------------------------------------------------------------- -#ifdef DEBUG_RLC_AM_BO - msg ("[RLC_AM][RB %d] BO : CH2 CONTROL %d DCCH %d\n", rlcP->rb_id, rlcP->control.nb_elements, rlcP->pdus_to_mac_layer_ch2.nb_elements); -#endif - return rlcP->control.nb_elements + rlcP->pdus_to_mac_layer_ch2.nb_elements; -} - -//----------------------------------------------------------------------------- -void -rlc_am_get_pdus (void *argP, uint8_t traffic_typeP) -{ - //----------------------------------------------------------------------------- - - struct rlc_am_entity *rlc = (struct rlc_am_entity *) argP; - - switch (rlc->protocol_state) { - - case RLC_NULL_STATE: - // from 3GPP TS 25.322 V4.2.0 - // In the NULL state the RLC entity does not exist and therefore it is not possible to transfer any data through it. - // Upon reception of a CRLC-CONFIG-Req from upper layer indicating establishment, the RLC entity: - // - is created; and - // - enters the DATA_TRANSFER_READY state. - break; - - case RLC_DATA_TRANSFER_READY_STATE: - // from 3GPP TS 25.322 V4.2.0 - // In the DATA_TRANSFER_READY state, acknowledged mode data can be exchanged between the entities according to subclause 11.3. - // Upon reception of a CRLC-CONFIG-Req from upper layer indicating release, the RLC entity: - // - enters the NULL state; and - // - is considered as being terminated. - // Upon detection of an initiating condition for the RLC reset procedure described in subclause 11.4.2, the RLC entity: - // - initiates the RLC reset procedure (see subclause 11.4); and - // - enters the RESET_PENDING state. - // Upon reception of a RESET PDU, the RLC entity responds according to subclause 11.4.3. - // Upon reception of a RESET ACK PDU, the RLC entity takes no action. - // Upon reception of CRLC-SUSPEND-Req from upper layer, the RLC entity is suspended and enters the LOCAL_SUSPEND state. - // SEND DATA TO MAC - - umts_timer_check_time_out (&rlc->rlc_am_timer_list, *rlc->frame_tick_milliseconds); - - if ((rlc->send_status_pdu_requested)) { - // may be timer status prohibit - if (rlc_am_send_status (rlc) > 0) { - rlc->send_status_pdu_requested = 0; - } - } else if ((rlc->timer_status_periodic) && ((Mac_rlc_xface->frame % (rlc->timer_status_periodic / 10)) == 0) - && (rlc->last_tx_status_frame != Mac_rlc_xface->frame)) { - // may be MAC can poll RLC more than once in a time frame - //msg ("[RLC_AM][RB %d] SEND STATUS PERIODIC frame %d\n", rlc->rb_id, Mac_rlc_xface->frame); - if (rlc_am_send_status (rlc) > 0) { - rlc->send_status_pdu_requested = 0; - } - - rlc->last_tx_status_frame = Mac_rlc_xface->frame; - } - -#ifdef NODE_MT - rlc_am_mux_ue (rlc, RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS | RLC_AM_TRAFFIC_ALLOWED_FOR_DATA); -#else - rlc_am_mux_rg (rlc, RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS | RLC_AM_TRAFFIC_ALLOWED_FOR_DATA); -#endif - - break; - - case RLC_RESET_PENDING_STATE: - // from 3GPP TS 25.322 V4.2.0 - // In the RESET_PENDING state the entity waits for a response from its peer entity and no data can be exchanged between the entities. - // Upon reception of a CRLC-CONFIG-Req from upper layer indicating release, the RLC entity: - // - enters the NULL state; and - // - is considered as being terminated. - // Upon reception of a RESET ACK PDU with the same RSN value as in the corresponding RESET PDU, the RLC entity: - // - acts according to subclause 11.4.4; and - // - enters the DATA_TRANSFER_READY state. - // Upon reception of a RESET ACK PDU with a different RSN value as in the corresponding RESET PDU, the RLC entity: - // - discards the RESET ACK PDU (see subclause 11.4.4); and - // - stays in the RESET_PENDING state. - // Upon reception of a RESET PDU, the RLC entity: - // - responds according to subclause 11.4.3; and - // - stays in the RESET_PENDING state. - // Upon reception of CRLC-SUSPEND-Req from upper layer, the RLC entity: - // - enters the RESET_AND_SUSPEND state. - umts_timer_check_time_out (&rlc->rlc_am_timer_list, *rlc->frame_tick_milliseconds); -#ifdef NODE_MT - rlc_am_mux_ue (rlc, RLC_AM_TRAFFIC_NOT_ALLOWED); -#else - rlc_am_mux_rg (rlc, RLC_AM_TRAFFIC_NOT_ALLOWED); -#endif - break; - - case RLC_RESET_AND_SUSPEND_STATE: - // In the RESET_ AND_SUSPEND state, the entity waits for a response from its peer entity or a primitive (CRLC-RESUME-Req) from its upper layer and no data can be exchanged between the entities. - // Upon reception of CRLC-CONFIG-Req from upper layer indicating release, the RLC entity: - // - enters the NULL state; and - // - is considered as being terminated. - // Upon reception of a RESET ACK PDU with the same RSN value as in the corresponding RESET PDU, the RLC entity: - // - acts according to subclause 11.4.4; and - // - enters the LOCAL_SUSPEND state. - // Upon reception of CRLC-RESUME-Req from upper layer in this state, the RLC entity: - // - is resumed, i.e. releases the suspend constraint; and - // - enters the RESET_PENDING state. -#ifdef NODE_MT - rlc_am_mux_ue (rlc, RLC_AM_TRAFFIC_NOT_ALLOWED); -#else - rlc_am_mux_rg (rlc, RLC_AM_TRAFFIC_NOT_ALLOWED); -#endif - break; - - case RLC_LOCAL_SUSPEND_STATE: - - // from 3GPP TS 25.322 V4.2.0 - // In the LOCAL_SUSPEND state, the RLC entity is suspended, i.e. it does not send AMD PDUs with SN greater than or equal to certain specified value (see subclause 9.7.5). - // Upon reception of CRLC-RESUME-Req from upper layers in this state, the RLC entity: - // - resumes the data transmission; and - // - enters the DATA_TRANSFER_READY state. - // Upon reception of CRLC-CONFIG-Req from upper layers indicating release, the RLC entity: - // - enters the NULL state; and - // - is considered as being terminated. - // Upon detection of an initiating condition for RLC reset procedure described in subclause 11.4.2, the RLC entity: - // - initiates the RLC reset procedure (see subclause 11.4); and - // - enters the RESET_AND_SUSPEND state. - - // TO DO TAKE CARE OF SN : THE IMPLEMENTATION OF THIS FUNCTIONNALITY IS NOT CRITICAL - if ((rlc->send_status_pdu_requested)) { - rlc_am_send_status (rlc); - rlc->send_status_pdu_requested = 0; - } - -#ifdef NODE_MT - rlc_am_mux_ue (rlc, RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS); -#else - rlc_am_mux_rg (rlc, RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS); -#endif - break; - - default: - msg ("[RLC_AM][RB %d] MAC_DATA_REQ UNKNOWN PROTOCOL STATE 0x%02X\n", rlc->rb_id, rlc->protocol_state); - } -} - -//----------------------------------------------------------------------------- -void -rlc_am_rx (void *argP, struct mac_data_ind data_indP) -{ - //----------------------------------------------------------------------------- - - struct rlc_am_entity *rlc = (struct rlc_am_entity *) argP; - -#ifdef DEBUG_RLC_AM_RX - msg("[RLC][AM] In rlc_am_rx\n"); -#endif - - switch (rlc->protocol_state) { - - case RLC_NULL_STATE: - // from 3GPP TS 25.322 V4.2.0 - // In the NULL state the RLC entity does not exist and therefore it is not possible to transfer any data through it. - // Upon reception of a CRLC-CONFIG-Req from upper layer indicating establishment, the RLC entity: - // - is created; and - // - enters the DATA_TRANSFER_READY state. - msg ("[RLC_AM %p] ERROR MAC_DATA_IND IN RLC_NULL_STATE\n", argP); - list_free (&data_indP.data); - break; - - case RLC_DATA_TRANSFER_READY_STATE: - - // from 3GPP TS 25.322 V4.2.0 - // In the DATA_TRANSFER_READY state, acknowledged mode data can be exchanged between the entities according to subclause 11.3. - // Upon reception of a CRLC-CONFIG-Req from upper layer indicating release, the RLC entity: - // - enters the NULL state; and - // - is considered as being terminated. - // Upon detection of an initiating condition for the RLC reset procedure described in subclause 11.4.2, the RLC entity: - // - initiates the RLC reset procedure (see subclause 11.4); and - // - enters the RESET_PENDING state. - // Upon reception of a RESET PDU, the RLC entity responds according to subclause 11.4.3. - // Upon reception of a RESET ACK PDU, the RLC entity takes no action. - // Upon reception of CRLC-SUSPEND-Req from upper layer, the RLC entity is suspended and enters the LOCAL_SUSPEND state. - if ((rlc->rlc_am_timer_list.head)) { - umts_timer_check_time_out (&rlc->rlc_am_timer_list, *rlc->frame_tick_milliseconds); - } - - rlc_am_demux_routing (rlc, RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS | RLC_AM_TRAFFIC_ALLOWED_FOR_DATA, data_indP); - break; - - case RLC_RESET_PENDING_STATE: - case RLC_RESET_AND_SUSPEND_STATE: - case RLC_LOCAL_SUSPEND_STATE: - - // from 3GPP TS 25.322 V4.2.0 - // In the RESET_PENDING state the entity waits for a response from its peer entity and no data can be exchanged between the entities. - // Upon reception of a CRLC-CONFIG-Req from upper layer indicating release, the RLC entity: - // - enters the NULL state; and - // - is considered as being terminated. - // Upon reception of a RESET ACK PDU with the same RSN value as in the corresponding RESET PDU, the RLC entity: - // - acts according to subclause 11.4.4; and - // - enters the DATA_TRANSFER_READY state. - // Upon reception of a RESET ACK PDU with a different RSN value as in the corresponding RESET PDU, the RLC entity: - // - discards the RESET ACK PDU (see subclause 11.4.4); and - // - stays in the RESET_PENDING state. - // Upon reception of a RESET PDU, the RLC entity: - // - responds according to subclause 11.4.3; and - // - stays in the RESET_PENDING state. - // Upon reception of CRLC-SUSPEND-Req from upper layer, the RLC entity: - // - enters the RESET_AND_SUSPEND state. - - // In the RESET_ AND_SUSPEND state, the entity waits for a response from its peer entity or a primitive (CRLC-RESUME-Req) from its upper layer and no data can be exchanged between the entities. - // Upon reception of CRLC-CONFIG-Req from upper layer indicating release, the RLC entity: - // - enters the NULL state; and - // - is considered as being terminated. - // Upon reception of a RESET ACK PDU with the same RSN value as in the corresponding RESET PDU, the RLC entity: - // - acts according to subclause 11.4.4; and - // - enters the LOCAL_SUSPEND state. - // Upon reception of CRLC-RESUME-Req from upper layer in this state, the RLC entity: - // - is resumed, i.e. releases the suspend constraint; and - // - enters the RESET_PENDING state. - - // from 3GPP TS 25.322 V4.2.0 - // In the LOCAL_SUSPEND state, the RLC entity is suspended, i.e. it does not send AMD PDUs with SN greater than or equal to certain specified value (see subclause 9.7.5). - // Upon reception of CRLC-RESUME-Req from upper layers in this state, the RLC entity: - // - resumes the data transmission; and - // - enters the DATA_TRANSFER_READY state. - // Upon reception of CRLC-CONFIG-Req from upper layers indicating release, the RLC entity: - // - enters the NULL state; and - // - is considered as being terminated. - // Upon detection of an initiating condition for RLC reset procedure described in subclause 11.4.2, the RLC entity: - // - initiates the RLC reset procedure (see subclause 11.4); and - // - enters the RESET_AND_SUSPEND state. - - if ((rlc->rlc_am_timer_list.head)) { - umts_timer_check_time_out (&rlc->rlc_am_timer_list, *rlc->frame_tick_milliseconds); - } - - rlc_am_demux_routing (rlc, RLC_AM_TRAFFIC_NOT_ALLOWED, data_indP); - break; - - default: - msg ("[RLC_AM %p] TX UNKNOWN PROTOCOL STATE 0x%02X\n", rlc, rlc->protocol_state); - } -} - -//----------------------------------------------------------------------------- -struct mac_status_resp -rlc_am_mac_status_indication (void *rlcP, uint16_t no_tbP, uint16_t tb_sizeP, struct mac_status_ind tx_statusP) -{ - //----------------------------------------------------------------------------- - struct mac_status_resp status_resp; - struct rlc_am_entity *rlc = (struct rlc_am_entity *) rlcP; - - - rlc_am_discard_check_sdu_time_out (rlc); - - // call only for knowing if control pdu to transmit - // special case: no data at startup on this side, but peer entity tx full sspeed - // peer entity wqit for acks - rlc_am_get_pdus (rlcP, RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS); - - rlc->nb_pdu_requested_by_mac_on_ch1 = no_tbP; - //((struct rlc_am_entity*)rlcP)->rlc_pdu_size = tb_sizeP; no modification of pdu_size for RLC AM - - status_resp.buffer_occupancy_in_pdus = rlc_am_get_buffer_occupancy_in_pdus_ch1 (rlc); - status_resp.buffer_occupancy_in_pdus += rlc_am_get_buffer_occupancy_in_pdus_ch2 (rlc); - status_resp.buffer_occupancy_in_pdus += rlc->control.nb_elements; - status_resp.buffer_occupancy_in_bytes = status_resp.buffer_occupancy_in_pdus * (rlc)->pdu_size; - status_resp.rlc_info.rlc_protocol_state = (rlc)->protocol_state; -#ifdef DEBUG_RLC_AM_TX - msg ("[RLC_AM][RB %d] MAC_STATUS_INDICATION %d TBs -> MAC_STATUS_RESPONSE %d TBs FRAME %d\n", rlc->rb_id, no_tbP, status_resp.buffer_occupancy_in_pdus, - Mac_rlc_xface->frame); -#endif - return status_resp; -} - -//----------------------------------------------------------------------------- -struct mac_status_resp -rlc_am_mac_status_indication_on_first_channel (void *rlcP, uint16_t no_tbP, uint16_t tb_sizeP, struct mac_status_ind tx_statusP) -{ - //----------------------------------------------------------------------------- - struct mac_status_resp status_resp; - - rlc_am_discard_check_sdu_time_out ((struct rlc_am_entity *) rlcP); - ((struct rlc_am_entity *) rlcP)->nb_pdu_requested_by_mac_on_ch1 = no_tbP; - //((struct rlc_am_entity*)rlcP)->rlc_pdu_size = tb_sizeP; no modification of pdu_size for RLC AM - - - status_resp.buffer_occupancy_in_pdus = rlc_am_get_buffer_occupancy_in_pdus_ch1 ((struct rlc_am_entity *) rlcP); - status_resp.buffer_occupancy_in_bytes = status_resp.buffer_occupancy_in_pdus * ((struct rlc_am_entity *) rlcP)->pdu_size; - status_resp.rlc_info.rlc_protocol_state = ((struct rlc_am_entity *) rlcP)->protocol_state; -#ifdef DEBUG_RLC_AM_TX - msg ("[RLC_AM][RB %d] CHANNEL 1 MAC_STATUS_INDICATION (DATA) %d TBs -> MAC_STATUS_RESPONSE %d TBs\n", ((struct rlc_am_entity*) rlcP)->rb_id, no_tbP, - status_resp.buffer_occupancy_in_pdus); -#endif - return status_resp; -} - -//----------------------------------------------------------------------------- -struct mac_status_resp -rlc_am_mac_status_indication_on_second_channel (void *rlcP, uint16_t no_tbP, uint16_t tb_sizeP, struct mac_status_ind tx_statusP) -{ - //----------------------------------------------------------------------------- - struct mac_status_resp status_resp; - - rlc_am_discard_check_sdu_time_out ((struct rlc_am_entity *) rlcP); - - ((struct rlc_am_entity *) rlcP)->nb_pdu_requested_by_mac_on_ch2 = no_tbP; - //((struct rlc_am_entity*)rlcP)->rlc_pdu_size = tb_sizeP; no modification of pdu_size for RLC AM - - status_resp.buffer_occupancy_in_pdus = rlc_am_get_buffer_occupancy_in_pdus_ch2 ((struct rlc_am_entity *) rlcP); - status_resp.buffer_occupancy_in_bytes = status_resp.buffer_occupancy_in_pdus * ((struct rlc_am_entity *) rlcP)->pdu_size; - status_resp.rlc_info.rlc_protocol_state = ((struct rlc_am_entity *) rlcP)->protocol_state; -#ifdef DEBUG_RLC_AM_TX - msg ("[RLC_AM][RB %d] CHANNEL 2 MAC_STATUS_INDICATION (CONTROL) %d TBs -> MAC_STATUS_RESPONSE %d TBs\n", ((struct rlc_am_entity*) rlcP)->rb_id, no_tbP, - status_resp.buffer_occupancy_in_pdus); -#endif - return status_resp; -} - -//----------------------------------------------------------------------------- -struct mac_data_req -rlc_am_mac_data_request (void *rlcP) -{ - //----------------------------------------------------------------------------- - struct mac_data_req data_req; - mem_block_t *pdu; - signed int nb_pdu_to_transmit = ((struct rlc_am_entity *) rlcP)->nb_pdu_requested_by_mac_on_ch1 ; - //rlc_am_get_pdus (rlcP, RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS | RLC_AM_TRAFFIC_ALLOWED_FOR_DATA); - rlc_am_get_pdus (rlcP, RLC_AM_TRAFFIC_ALLOWED_FOR_DATA); - - list_init (&data_req.data, NULL); - - //list_add_list (&((struct rlc_am_entity *) rlcP)->pdus_to_mac_layer_ch1, &data_req.data); - while (nb_pdu_to_transmit > 0 ) { - pdu = list_remove_head (&((struct rlc_am_entity *) rlcP)->pdus_to_mac_layer_ch1); - - if (pdu != null) { - list_add_tail_eurecom (pdu, &data_req.data); - } else { - //msg ("[RLC_AM][RB %d] WARNING MAC_DATA_REQUEST CANNOT GIVE A PDU REQUESTED BY MAC\n", ((struct rlc_am_entity *) rlcP)->rb_id); - } - - nb_pdu_to_transmit = nb_pdu_to_transmit - 1; - } - - //list_add_list (&((struct rlc_am_entity *) rlcP)->pdus_to_mac_layer_ch2, &data_req.data); - -#ifdef DEBUG_RLC_AM_TX - msg ("[RLC_AM][RB %d] MAC_DATA_REQUEST %d TBs (REQUESTED %d) Frame %d\n", ((struct rlc_am_entity *) rlcP)->rb_id, data_req.data.nb_elements, - ((struct rlc_am_entity *) rlcP)->nb_pdu_requested_by_mac_on_ch1 , Mac_rlc_xface->frame); -#endif - data_req.buffer_occupancy_in_pdus = rlc_am_get_buffer_occupancy_in_pdus_ch1 ((struct rlc_am_entity *) rlcP); - data_req.buffer_occupancy_in_pdus += rlc_am_get_buffer_occupancy_in_pdus_ch2 ((struct rlc_am_entity *) rlcP); - data_req.buffer_occupancy_in_bytes = data_req.buffer_occupancy_in_pdus * ((struct rlc_am_entity *) rlcP)->pdu_size; - data_req.rlc_info.rlc_protocol_state = ((struct rlc_am_entity *) rlcP)->protocol_state; - return data_req; -} - -//----------------------------------------------------------------------------- -struct mac_data_req -rlc_am_mac_data_request_on_first_channel (void *rlcP) -{ - //----------------------------------------------------------------------------- - struct mac_data_req data_req; - // from TS25.322 V4.2.0 p13 - // In case two logical channels are configured in the uplink, AMD PDUs are transmitted - // on the first logical channel, and control PDUs are transmitted on the second logical - // channel. In case two logical channels are configured in the downlink, AMD and Control - // PDUs can be transmitted on any of the two logical channels. -#ifdef NODE_RG - rlc_am_get_pdus (rlcP, RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS | RLC_AM_TRAFFIC_ALLOWED_FOR_DATA); -#else - rlc_am_get_pdus (rlcP, RLC_AM_TRAFFIC_ALLOWED_FOR_DATA); -#endif - list_init (&data_req.data, NULL); - list_add_list (&((struct rlc_am_entity *) rlcP)->pdus_to_mac_layer_ch1, &data_req.data); - -#ifdef DEBUG_RLC_AM_TX - msg ("[RLC_AM][RB %d] MAC_DATA_REQUEST (DATA) %d TBs\n", ((struct rlc_am_entity *) rlcP)->rb_id, data_req.data.nb_elements); -#endif - data_req.buffer_occupancy_in_pdus = rlc_am_get_buffer_occupancy_in_pdus_ch1 ((struct rlc_am_entity *) rlcP); - data_req.buffer_occupancy_in_bytes = rlc_am_get_buffer_occupancy_in_bytes_ch1 ((struct rlc_am_entity *) rlcP); - data_req.rlc_info.rlc_protocol_state = ((struct rlc_am_entity *) rlcP)->protocol_state; - return data_req; -} - -//----------------------------------------------------------------------------- -struct mac_data_req -rlc_am_mac_data_request_on_second_channel (void *rlcP) -{ - //----------------------------------------------------------------------------- - struct mac_data_req data_req; - - // from TS25.322 V4.2.0 p13 - // In case two logical channels are configured in the uplink, AMD PDUs are transmitted - // on the first logical channel, and control PDUs are transmitted on the second logical - // channel. In case two logical channels are configured in the downlink, AMD and Control - // PDUs can be transmitted on any of the two logical channels. -#ifdef NODE_RG - rlc_am_get_pdus (rlcP, RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS | RLC_AM_TRAFFIC_ALLOWED_FOR_DATA); -#else - rlc_am_get_pdus (rlcP, RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS); -#endif - list_init (&data_req.data, NULL); - list_add_list (&((struct rlc_am_entity *) rlcP)->pdus_to_mac_layer_ch2, &data_req.data); - -#ifdef DEBUG_RLC_AM_TX - msg ("[RLC_AM][RB %d] MAC_DATA_REQUEST (CONTROL) %d TBs\n", ((struct rlc_am_entity *) rlcP)->rb_id, data_req.data.nb_elements); -#endif - data_req.buffer_occupancy_in_pdus = rlc_am_get_buffer_occupancy_in_pdus_ch2 ((struct rlc_am_entity *) rlcP); - data_req.buffer_occupancy_in_bytes = rlc_am_get_buffer_occupancy_in_bytes_ch2 ((struct rlc_am_entity *) rlcP); - data_req.rlc_info.rlc_protocol_state = ((struct rlc_am_entity *) rlcP)->protocol_state; - return data_req; -} - -//----------------------------------------------------------------------------- -void -rlc_am_mac_data_indication (void *rlcP, struct mac_data_ind data_indP) -{ - //----------------------------------------------------------------------------- - rlc_am_rx (rlcP, data_indP); -} - -//----------------------------------------------------------------------------- -void -rlc_am_data_req (void *rlcP, mem_block_t * sduP) -{ - //----------------------------------------------------------------------------- - struct rlc_am_entity *rlc = (struct rlc_am_entity *) rlcP; - uint32_t mui; - uint16_t data_offset; - uint16_t data_size; - uint8_t conf; - - - if ((rlc->input_sdus[rlc->next_sdu_index] == NULL) && (((rlc->next_sdu_index + 1) % rlc->size_input_sdus_buffer) != rlc->current_sdu_index)) { - - rlc->stat_tx_pdcp_sdu += 1; - - rlc->input_sdus[rlc->next_sdu_index] = sduP; - mui = ((struct rlc_am_data_req *) (sduP->data))->mui; - data_offset = ((struct rlc_am_data_req *) (sduP->data))->data_offset; - data_size = ((struct rlc_am_data_req *) (sduP->data))->data_size; - conf = ((struct rlc_am_data_req *) (sduP->data))->conf; - - ((struct rlc_am_tx_sdu_management *) (sduP->data))->mui = mui; - ((struct rlc_am_tx_sdu_management *) (sduP->data))->sdu_size = data_size; - ((struct rlc_am_tx_sdu_management *) (sduP->data))->confirm = conf; - - rlc->buffer_occupancy += ((struct rlc_am_tx_sdu_management *) (sduP->data))->sdu_size; - rlc->nb_sdu += 1; - - ((struct rlc_am_tx_sdu_management *) (sduP->data))->first_byte = &sduP->data[data_offset]; - ((struct rlc_am_tx_sdu_management *) (sduP->data))->sdu_remaining_size = ((struct rlc_am_tx_sdu_management *) (sduP->data))->sdu_size; - ((struct rlc_am_tx_sdu_management *) (sduP->data))->sdu_segmented_size = 0; - ((struct rlc_am_tx_sdu_management *) (sduP->data))->sdu_creation_time = *rlc->frame_tick_milliseconds; - ((struct rlc_am_tx_sdu_management *) (sduP->data))->nb_pdus = 0; - ((struct rlc_am_tx_sdu_management *) (sduP->data))->nb_pdus_ack = 0; - ((struct rlc_am_tx_sdu_management *) (sduP->data))->nb_pdus_time = 0; - ((struct rlc_am_tx_sdu_management *) (sduP->data))->nb_pdus_internal_use = 0; - ((struct rlc_am_tx_sdu_management *) (sduP->data))->segmented = 0; - ((struct rlc_am_tx_sdu_management *) (sduP->data))->discarded = 0; - ((struct rlc_am_tx_sdu_management *) (sduP->data))->li_index_for_discard = -1; - ((struct rlc_am_tx_sdu_management *) (sduP->data))->no_new_sdu_segmented_in_last_pdu = 0; - rlc->next_sdu_index = (rlc->next_sdu_index + 1) % rlc->size_input_sdus_buffer; -#ifdef DEBUG_RLC_AM_DATA_REQUEST - msg ("[RLC_AM][RB %d] RLC_AM_DATA_REQ size %d Bytes, NB SDU %d current_sdu_index=%d next_sdu_index=%d conf %d mui %d ", - rlc->rb_id, data_size, rlc->nb_sdu, rlc->current_sdu_index, rlc->next_sdu_index, conf, mui); - msg ("BO=%ld Bytes\n", rlc->buffer_occupancy); -#endif - } else { -#ifdef DEBUG_RLC_AM_DATA_REQUEST - msg ("[RLC_AM][RB %d] RLC_AM_DATA_REQ BUFFER FULL, NB SDU %d current_sdu_index=%d next_sdu_index=%d size_input_sdus_buffer=%d\n", - rlc->rb_id, rlc->nb_sdu, rlc->current_sdu_index, rlc->next_sdu_index, rlc->size_input_sdus_buffer); -#endif - rlc->stat_tx_pdcp_sdu_discarded += 1; - free_mem_block (sduP); - } -} diff --git a/openair2/LAYER2/RLC/AM/rlc_am_constants.h b/openair2/LAYER2/RLC/AM/rlc_am_constants.h deleted file mode 100755 index ec34782266987817c9a3e0e4360453459bf171db..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_constants.h +++ /dev/null @@ -1,153 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_constant.h - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - ***************************************************************************/ -# ifndef __RLC_AM_CONSTANT_H__ -# define __RLC_AM_CONSTANT_H__ - -# define RLC_AM_LOCATION_UTRAN 0xBA -# define RLC_AM_LOCATION_UE 0x01 - -//---------------------------------------------------------- -// AMD DATA, CONTROL PDU parameters -//---------------------------------------------------------- -# define NB_MAX_SUFI 30 -# define SUFI_MAX_SIZE 40 -// SUFI field (4 bits) -# define RLC_AM_SUFI_NO_MORE 0x0 -# define RLC_AM_SUFI_WINDOW 0x1 -# define RLC_AM_SUFI_ACK 0x2 -# define RLC_AM_SUFI_LIST 0x3 -# define RLC_AM_SUFI_BITMAP 0x4 -# define RLC_AM_SUFI_RLIST 0x5 -# define RLC_AM_SUFI_MRW 0x6 -# define RLC_AM_SUFI_MRW_ACK 0x7 - -# define RLC_AM_SUFI_NO_MORE_SIZE 4 -//in bits -# define RLC_AM_SUFI_ACK_SIZE 16 -//in bits -# define RLC_AM_SUFI_LIST_SIZE_MIN 24 -//in bits -# define RLC_AM_SUFI_BITMAP_SIZE_MIN 28 -//in bits -//---------------------------------------------------------- -// values for ack field of struct rlc_am_tx_pdu_management -// this struct is mapped on the misc field of each pdu -# define RLC_AM_PDU_ACK_NO_EVENT 0 -# define RLC_AM_PDU_ACK_EVENT 1 -# define RLC_AM_PDU_NACK_EVENT -1 -//---------------------------------------------------------- -# define RLC_AM_SEND_MRW_OFF 0x0F -# define RLC_AM_SEND_MRW_ON 0xF0 -//---------------------------------------------------------- -// SN Field -# define RLC_AM_SN_1ST_PART_MASK 0x7F -# define RLC_AM_SN_2ND_PART_MASK 0xF8 -//---------------------------------------------------------- -// Polling bit (values shifted 2 bits left) -# define RLC_AM_P_STATUS_REPORT_NOT_REQUESTED 0 -# define RLC_AM_P_STATUS_REPORT_REQUESTED 4 -# define RLC_AM_P_STATUS_REPORT_MASK 4 -//---------------------------------------------------------- -// li field (values shifted 1 bit left) -# define RLC_AM_SEGMENT_NB_MAX_LI_PER_PDU 32 -//---------------------------------------------------------- -// shifted 3 bits left -# define RLC_AM_RESET_SEQUENCE_NUMBER_MASK 0x08 - -# define RLC_AM_TIMER_POLL_TIME_OUT_EVENT 0x001 -# define RLC_AM_TIMER_POLL_PROHIBIT_TIME_OUT_EVENT 0x002 -# define RLC_AM_TIMER_EPC_TIME_OUT_EVENT 0x004 -# define RLC_AM_TIMER_DISCARD_TIME_OUT_EVENT 0x008 -# define RLC_AM_TIMER_POLL_PERIODIC_TIME_OUT_EVENT 0x010 -# define RLC_AM_TIMER_STATUS_PROHIBIT_TIME_OUT_EVENT 0x020 -# define RLC_AM_TIMER_STATUS_PERIODIC_TIME_OUT_EVENT 0x040 -# define RLC_AM_TIMER_RST_TIME_OUT_EVENT 0x080 -# define RLC_AM_TIMER_MRW_TIME_OUT_EVENT 0x100 -//---------------------------------------------------------- -# define RLC_AM_SDU_SEGMENTS_SUBMITTED_TO_LOWER_LAYER 0xFF -// for sdu_header_copy -# define RLC_AM_SN_INVALID 0xFFFF - -// PDU transmission -# define RLC_AM_PDU_COPY_LOCATION_RETRANSMISSION_BUFFER_TO_SEND 0x10 -# define RLC_AM_PDU_COPY_LOCATION_PDUS_TO_MAC_LAYER 0x20 -# define RLC_AM_PDU_COPY_LOCATION_MASK 0xF0 -//---------------------------------------------------------- -// Events defined for state model of the acknowledged mode entity -# define RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_NULL_STATE_EVENT 0x00 -# define RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_DATA_TRANSFER_READY_STATE_EVENT 0x01 -# define RLC_AM_RECEIVE_CRLC_SUSPEND_REQ_EVENT 0x10 -# define RLC_AM_TRANSMIT_CRLC_SUSPEND_CNF_EVENT 0x11 -# define RLC_AM_RECEIVE_CRLC_RESUME_REQ_EVENT 0x12 -# define RLC_AM_RECEIVE_RESET_EVENT 0x20 -# define RLC_AM_TRANSMIT_RESET_EVENT 0x21 -# define RLC_AM_RECEIVE_RESET_ACK_EVENT 0x22 -# define RLC_AM_TRANSMIT_RESET_ACK_EVENT 0x23 -//---------------------------------------------------------- -# define RLC_AM_TRAFFIC_NOT_ALLOWED 0x00 -# define RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS 0xC0 -// mutual exclusion of set bits with next value -# define RLC_AM_TRAFFIC_ALLOWED_FOR_DATA 0x0D -// mutual exclusion of set bits with previous value - -# define RLC_AM_DCCH_ID 0xC0 -// mutual exclusion of set bits with next value -# define RLC_AM_DTCH_ID 0x0D -// mutual exclusion of set bits with previous value -//---------------------------------------------------------- -// for status report of transmission by MAC layer -# define RLC_AM_STATUS_PDU_TYPE 0x0001 -# define RLC_AM_FIRST_STATUS_PDU_TYPE 0x0011 -# define RLC_AM_LAST_STATUS_PDU_TYPE 0x0021 -# define RLC_AM_MRW_STATUS_PDU_TYPE 0x0040 -# define RLC_AM_RESET_PDU_TYPE 0x0080 -# define RLC_AM_RESET_ACK_PDU_TYPE 0x0100 -# define RLC_AM_DATA_POLL_PDU_TYPE 0x1800 -# define RLC_AM_DATA_PDU_TYPE 0x1000 -//---------------------------------------------------------- -// TIMER EPC -# define TIMER_EPC_STATE_IDLE 0x00 -# define TIMER_EPC_STATE_TIMER_ARMED 0x01 -# define TIMER_EPC_STATE_TIMED_OUT 0x02 -# define TIMER_EPC_STATE_VR_EP_COUNTING_DOWN 0x04 -# define TIMER_EPC_STATE_VR_EP_EQUAL_ZERO 0x08 - -# define TIMER_EPC_PDU_STATUS_SUBMITTED_LOWER_LAYER_EVENT 0x01 -# define TIMER_EPC_PDU_STATUS_TRANSMITED_EVENT 0x02 -# define TIMER_EPC_TIMER_TIMED_OUT_EVENT 0x04 -# define TIMER_EPC_VR_EP_EQUAL_ZERO_EVENT 0x08 -# endif diff --git a/openair2/LAYER2/RLC/AM/rlc_am_control_primitives.c b/openair2/LAYER2/RLC/AM/rlc_am_control_primitives.c deleted file mode 100755 index 24d17e26b88eb645b058a467dc8e7588e1760823..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_control_primitives.c +++ /dev/null @@ -1,482 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_control_primitives.c - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - ***************************************************************************/ -#include "rtos_header.h" -#include "platform_types.h" -//----------------------------------------------------------------------------- -#include "rlc_am_entity.h" -#include "rlc_am_reset_proto_extern.h" -#include "rlc_am_errno.h" -#include "umts_timer_proto_extern.h" -#include "rlc_primitives.h" -#include "rlc_am_fsm_proto_extern.h" -#include "rlc_am_segment_proto_extern.h" -#include "rrm_config_structs.h" -#include "LAYER2/MAC/extern.h" -//----------------------------------------------------------------------------- -void config_req_rlc_am (struct rlc_am_entity* rlcP, module_id_t module_idP, rlc_am_info_t* config_amP, uint8_t rb_idP, rb_type_t rb_typeP); -void send_rlc_am_control_primitive (struct rlc_am_entity* rlcP, module_id_t module_idP, mem_block_t* cprimitiveP); -void init_rlc_am (struct rlc_am_entity* rlcP); -void rlc_am_reset_state_variables (struct rlc_am_entity* rlcP); -void rlc_am_alloc_buffers_after_establishment (struct rlc_am_entity* rlcP); -void rlc_am_discard_all_pdus (struct rlc_am_entity* rlcP); -void rlc_am_stop_all_timers (struct rlc_am_entity* rlcP); -void rlc_am_free_all_resources (struct rlc_am_entity* rlcP); -void rlc_am_set_configured_parameters (struct rlc_am_entity* rlcP, mem_block_t* cprimitiveP); -//void rlc_am_probing_get_buffer_occupancy_measurements (struct rlc_am_entity *rlcP, probing_report_traffic_rb_parameters *reportP, int measurement_indexP); -//----------------------------------------------------------------------------- -/*void -rlc_am_probing_get_buffer_occupancy_measurements (struct rlc_am_entity *rlcP, probing_report_traffic_rb_parameters *reportP, int measurement_indexP) -{ -//----------------------------------------------------------------------------- - if (rlcP->protocol_state != RLC_NULL_STATE) { - reportP->incoming_sdu[measurement_indexP] = rlcP->buffer_occupancy; - reportP->retransmission[measurement_indexP] = rlcP->buffer_occupancy_retransmission_buffer * rlcP->pdu_size; - reportP->ready_to_send[measurement_indexP] = (rlcP->pdus_to_mac_layer_ch1.nb_elements + rlcP->pdus_to_mac_layer_ch2.nb_elements) * rlcP->pdu_size; - } -}*/ -//----------------------------------------------------------------------------- -void -config_req_rlc_am (struct rlc_am_entity* rlcP, module_id_t module_idP, rlc_am_info_t* config_amP, uint8_t rb_idP, rb_type_t rb_typeP) -{ - //----------------------------------------------------------------------------- - mem_block_t* mb; - mb = get_free_mem_block (sizeof (struct crlc_primitive)); - ((struct crlc_primitive*) mb->data)->type = CRLC_CONFIG_REQ; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.e_r = RLC_E_R_ESTABLISHMENT; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.stop = 0; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.cont = 1; - // timers - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.timer_poll = config_amP->timer_poll; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.timer_poll_prohibit = config_amP->timer_poll_prohibit; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.timer_discard = config_amP->timer_discard; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.timer_poll_periodic = config_amP->timer_poll_periodic; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.timer_status_prohibit = config_amP->timer_status_prohibit; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.timer_status_periodic = config_amP->timer_status_periodic; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.timer_rst = config_amP->timer_rst; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.max_rst = config_amP->max_rst; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.timer_mrw = config_amP->timer_mrw; - // protocol_parameters - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.pdu_size = config_amP->pdu_size; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.max_dat = config_amP->max_dat; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.poll_pdu = config_amP->poll_pdu; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.poll_sdu = config_amP->poll_sdu; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.poll_window = config_amP->poll_window; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.configured_tx_window_size = config_amP->tx_window_size; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.configured_rx_window_size = config_amP->rx_window_size; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.max_mrw = config_amP->max_mrw; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.last_transmission_pdu_poll_trigger = - config_amP->last_transmission_pdu_poll_trigger; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.last_retransmission_pdu_poll_trigger = - config_amP->last_retransmission_pdu_poll_trigger; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.sdu_discard_mode = config_amP->sdu_discard_mode; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.send_mrw = config_amP->send_mrw; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.frame_tick_milliseconds = &mac_xface->frame; - ((struct crlc_primitive*) mb->data)->primitive.c_config_req.parameters.am_parameters.rb_id = rb_idP; - send_rlc_am_control_primitive (rlcP, module_idP, mb); - - if (rb_typeP != SIGNALLING_RADIO_BEARER) { - rlcP->data_plane = 1; - msg ("[RLC AM][RB %d] DATA PLANE\n", rlcP->rb_id); - - } else { - rlcP->data_plane = 0; - msg ("[RLC AM][RB %d] CONTROL PLANE\n", rlcP->rb_id); - } -} -//----------------------------------------------------------------------------- -void -send_rlc_am_control_primitive (struct rlc_am_entity* rlcP, module_id_t module_idP, mem_block_t* cprimitiveP) -{ - //----------------------------------------------------------------------------- - rlcP->module_id = module_idP; - - switch (((struct crlc_primitive*) cprimitiveP->data)->type) { - case CRLC_CONFIG_REQ: - switch (((struct crlc_primitive*) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.e_r) { - case RLC_E_R_ESTABLISHMENT: - if (rlc_am_fsm_notify_event (rlcP, RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_DATA_TRANSFER_READY_STATE_EVENT)) { - rlc_am_set_configured_parameters (rlcP, cprimitiveP); // the order of the calling of procedures... - rlc_am_reset_state_variables (rlcP); // ...must not ... - rlc_am_alloc_buffers_after_establishment (rlcP); // ...be changed - } - - break; - - case RLC_E_R_RE_ESTABLISHMENT: - - // from 3GPP TS 25.322 V4.2.0(2001-09) - // The RLC re-establishment function is applicable for AM and UM and is used when upper layers request an RLC entity to be re-established. - // When an RLC entity is re-established by upper layers, the RLC entity shall: - // - reset the state variables to their initial value; - // - set the configurable parameters to their configured value; - // - set the hyper frame number (HFN) in UL and DL to the value configured by upper layers; - // - if the RLC entity is operating in unacknowledged mode: - // - if it is a receiving UM RLC entity: - // - discard all UMD PDUs; - // - if it is a transmitting UM RLC entity: - // - discard the RLC SDUs for which one or more segments have been submitted to a lower layer; - // - otherwise if the RLC entity is operating in acknowledged mode: - // - discard all AMD PDUs in the Receiver and Sender. - if (rlc_am_fsm_notify_event (rlcP, RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_DATA_TRANSFER_READY_STATE_EVENT)) { - rlc_am_free_all_resources (rlcP); - rlc_am_set_configured_parameters (rlcP, cprimitiveP); // the order of the calling of procedures... - rlc_am_reset_state_variables (rlcP); // ...must not ... - rlc_am_alloc_buffers_after_establishment (rlcP); // ...be changed - } - - break; - - case RLC_E_R_MODIFICATION: - msg ("[RLC_AM][RB %d] WARNING CRLC_CONFIG_REQ:RLC_AM_E_R_MODIFICATION NOT IMPLEMENTED AT ALL: MAY BE BUGGY IF CHANGING WINDOWS SIZE\n", rlcP->rb_id); - rlc_am_set_configured_parameters (rlcP, cprimitiveP); - break; - - case RLC_E_R_RELEASE: - if (rlc_am_fsm_notify_event (rlcP, RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_NULL_STATE_EVENT)) { - rlc_am_free_all_resources (rlcP); - } - - break; - - default: - msg ("[RLC_AM][ERROR] control_rlc_am(CRLC_CONFIG_REQ) unknown parameter E_R\n"); - } - - break; - - case CRLC_SUSPEND_REQ: - - // from 3GPP TS 25.322 V4.2.0(2001-09) - // When an RLC entity operating in acknowledged mode is suspended by upper layers with the parameter N, the RLC entity shall: - // - acknowledge the suspend request with a confirmation containing the current value of VT(S); - // - not send AMD PDUs with sequence number SNVT(S)+N. - if (rlc_am_fsm_notify_event (rlcP, RLC_AM_RECEIVE_CRLC_SUSPEND_REQ_EVENT)) { - if ((rlcP->protocol_state == RLC_LOCAL_SUSPEND_STATE) || (rlcP->protocol_state == RLC_LOCAL_SUSPEND_STATE)) { - // TO DO IN FUTURE, BUT IT SEEMS THERE IS NO NEED TO IMPLEMENT THIS FUNCTION IN THE CURRENTLY DEFINED ARCHITECTURE - // SO DISPLAY ERROR MESSAGE - msg ("[RLC_AM[RB %d] ERROR RECEIVED CRLC_SUSPEND_REQ NOT IMPLEMENTED AT ALL, RLC_AM MAY NOT WORK AS EXPECTED IN THE 3GPP SPECIFICATION\n", rlcP->rb_id); - } - } - - break; - - case CRLC_RESUME_REQ: - - // from 3GPP TS 25.322 V4.2.0(2001-09) - // When an RLC entity operating in acknowledged mode is resumed by upper layers, the RLC entity shall: - // - if the RLC entity is suspended and a RLC Reset procedure is not ongoing: - // - resume data transfer procedure. - // - otherwise, if the RLC entity is suspended and a RLC Reset procedure is ongoing: - // - remove the suspend constraint; - // - resume the RLC reset procedure according to subclause 11.4. - if (rlc_am_fsm_notify_event (rlcP, RLC_AM_RECEIVE_CRLC_RESUME_REQ_EVENT)) { - if ((rlcP->protocol_state == RLC_RESET_PENDING_STATE) || (rlcP->protocol_state == RLC_DATA_TRANSFER_READY_STATE)) { - // TO DO IN FUTURE, BUT IT SEEMS THERE IS NO NEED TO IMPLEMENT THIS FUNCTION IN THE CURRENTLY DEFINED ARCHITECTURE - // SO DISPLAY ERROR MESSAGE - msg ("[RLC_AM][RB %d] ERROR RECEIVED CRLC_RESUME_REQ NOT IMPLEMENTED AT ALL, RLC_AM MAY NOT WORK AS EXPECTED IN THE 3GPP SPECIFICATION\n", rlcP->rb_id); - } - } - - break; - - default: - msg ("[RLC_AM][RB %d][ERROR] control_rlc_am(UNKNOWN CPRIMITIVE)\n", rlcP->rb_id); - } - - free_mem_block (cprimitiveP); -} - -//----------------------------------------------------------------------------- -void -init_rlc_am (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - memset (rlcP, 0, sizeof (struct rlc_am_entity)); - list2_init (&rlcP->retransmission_buffer_to_send, NULL); - list_init (&rlcP->pdus_to_mac_layer_ch1, NULL); - list_init (&rlcP->pdus_to_mac_layer_ch2, NULL); - list_init (&rlcP->pdus_from_mac_layer_ch1, NULL); - list_init (&rlcP->pdus_from_mac_layer_ch2, NULL); - list_init (&rlcP->control, NULL); - list2_init (&rlcP->sdu_conf_segmented, NULL); - list2_init (&rlcP->sdu_discard_segmented, NULL); - list2_init (&rlcP->sdu_discarded, NULL); - list2_init (&rlcP->rlc_am_timer_list, NULL); - rlcP->protocol_state = RLC_NULL_STATE; - rlcP->next_sdu_index = 0; - rlcP->current_sdu_index = 0; - rlcP->last_received_rsn = 0xFF; - //-------------------------------------------------------------------------- - rlcP->discard_reassembly_after_li = RLC_AM_DISCARD_REASSEMBLY_AT_LI_INDEX_0; - rlcP->discard_reassembly_start_sn = RLC_AM_SN_INVALID; // =>not activated - rlcP->stat_tx_pdcp_sdu = 0; - rlcP->stat_tx_pdcp_sdu_discarded = 0; - rlcP->stat_tx_retransmit_pdu_unblock = 0; - rlcP->stat_tx_retransmit_pdu_by_status = 0; - rlcP->stat_tx_data_pdu = 0; - rlcP->stat_tx_control_pdu = 0; - rlcP->stat_rx_sdu = 0; - rlcP->stat_rx_error_pdu = 0; - rlcP->stat_rx_data_pdu = 0; - rlcP->stat_rx_data_pdu_out_of_window = 0; - rlcP->stat_rx_control_pdu = 0; -} - -//----------------------------------------------------------------------------- -void -rlc_am_alloc_buffers_after_establishment (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - rlcP->recomputed_configured_tx_window_size = 1; - - while (rlcP->recomputed_configured_tx_window_size < rlcP->configured_tx_window_size) { - rlcP->recomputed_configured_tx_window_size = rlcP->recomputed_configured_tx_window_size << 1; - } - - rlcP->retransmission_buffer_alloc = get_free_mem_block (rlcP->recomputed_configured_tx_window_size * sizeof (mem_block_t*)); - rlcP->retransmission_buffer = (mem_block_t**) (rlcP->retransmission_buffer_alloc->data); - //memset (rlcP->retransmission_buffer, 0, rlcP->recomputed_configured_tx_window_size * sizeof (mem_block_t *)); - rlcP->recomputed_configured_rx_window_size = 1; - - while (rlcP->recomputed_configured_rx_window_size < rlcP->configured_rx_window_size) { - rlcP->recomputed_configured_rx_window_size = rlcP->recomputed_configured_rx_window_size << 1; - } - - rlcP->receiver_buffer_alloc = get_free_mem_block (rlcP->recomputed_configured_rx_window_size * sizeof (mem_block_t*)); - rlcP->receiver_buffer = (mem_block_t**) (rlcP->receiver_buffer_alloc->data); - msg("[RLC AM][RB %d] Window size %d\n",rlcP->rb_id,rlcP->recomputed_configured_rx_window_size); - //memset (rlcP->receiver_buffer, 0, rlcP->recomputed_configured_rx_window_size * sizeof (mem_block_t *)); - rlcP->holes_alloc = get_free_mem_block ((rlcP->recomputed_configured_rx_window_size * sizeof (struct rlc_am_hole)) >> 1); - rlcP->holes = (struct rlc_am_hole*) (rlcP->holes_alloc->data); - //memset (rlcP->holes_alloc->data, 0, (rlcP->recomputed_configured_rx_window_size * sizeof (mem_block_t *)) >> 1); - rlcP->size_input_sdus_buffer = rlcP->recomputed_configured_tx_window_size * 4; - - if ((rlcP->input_sdus_alloc == NULL)) { - rlcP->input_sdus_alloc = get_free_mem_block (rlcP->size_input_sdus_buffer * sizeof (void*)); - rlcP->input_sdus = (mem_block_t**) (rlcP->input_sdus_alloc->data); - //memset (rlcP->input_sdus, 0, rlcP->size_input_sdus_buffer * sizeof (void *)); - } -} - -//----------------------------------------------------------------------------- -void -rlc_am_reset_state_variables (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - rlcP->vt_s = 0; - rlcP->vt_a = 0; - rlcP->vt_pdu = 0; - //................................................................ - rlcP->vt_sdu = 0; - rlcP->vt_mrw = 0; - rlcP->vt_ms = rlcP->configured_tx_window_size - 1; - //................................................................ - rlcP->vt_ws = rlcP->configured_tx_window_size; - rlcP->vr_r = 0; - rlcP->vr_h = 0; - //................................................................ - rlcP->vr_mr = rlcP->configured_rx_window_size - 1; - rlcP->vt_rst = 0; - //................................................................ - rlcP->send_status_pdu_requested = 0; - rlcP->first_li_in_next_pdu = RLC_LI_UNDEFINED; - rlcP->last_reassemblied_sn = SN_12BITS_MASK; - rlcP->li_exactly_filled_to_add_in_next_pdu = 0; - rlcP->li_one_byte_short_to_add_in_next_pdu = 0; - //................................................................ - rlcP->sufi_to_insert_index = 0; - rlcP->ack.vr_r_modified = 0; - rlcP->ack.ack_other_vr_r = 0; - //................................................................ - rlcP->output_sdu_size_to_write = 0; - rlcP->discard_reassembly_after_li = RLC_AM_DISCARD_REASSEMBLY_AT_LI_INDEX_0; - rlcP->discard_reassembly_start_sn = RLC_AM_SN_INVALID; // =>not activated - //................................................................ - rlcP->timer_mrw = NULL; - //................................................................ - rlcP->buffer_occupancy = 0; - rlcP->nb_sdu = 0; - rlcP->buffer_occupancy_retransmission_buffer = 0; - rlcP->next_sdu_index = 0; - rlcP->current_sdu_index = 0; - rlcP->nb_pdu_requested_by_mac_on_ch1 = 0; - rlcP->nb_pdu_requested_by_mac_on_ch2 = 0; - rlcP->running_timer_status_prohibit = rlcP->timer_status_prohibit/10; -} - -//----------------------------------------------------------------------------- -void -rlc_am_stop_all_timers (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - list2_free (&rlcP->rlc_am_timer_list); -} - -//----------------------------------------------------------------------------- -void -rlc_am_discard_all_pdus (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - uint16_t index; - index = 0; - - while (index < rlcP->recomputed_configured_rx_window_size) { - if (rlcP->receiver_buffer[index] != NULL) { - free_mem_block (rlcP->receiver_buffer[index]); - rlcP->receiver_buffer[index] = NULL; - } - - index++; - } - - index = 0; - - while (index < rlcP->recomputed_configured_tx_window_size) { - if (rlcP->retransmission_buffer[index] != NULL) { - free_mem_block (rlcP->retransmission_buffer[index]); - rlcP->retransmission_buffer[index] = NULL; - } - - index++; - } - - list2_free (&rlcP->retransmission_buffer_to_send); - list_free (&rlcP->pdus_to_mac_layer_ch1); - list_free (&rlcP->pdus_to_mac_layer_ch2); - list_free (&rlcP->control); - - if ((rlcP->output_sdu_in_construction)) { - free_mem_block (rlcP->output_sdu_in_construction); - rlcP->output_sdu_in_construction = NULL; - } -} - -//----------------------------------------------------------------------------- -void -rlc_am_free_all_resources (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - int index; - - for (index = 0; index < rlcP->size_input_sdus_buffer; index++) { - if (rlcP->input_sdus[index]) { - free_mem_block (rlcP->input_sdus[index]); - rlcP->input_sdus[index] = NULL; - } - } - - rlc_am_discard_all_pdus (rlcP); - - if (rlcP->retransmission_buffer_alloc) { - free_mem_block (rlcP->retransmission_buffer_alloc); - } - - if (rlcP->receiver_buffer_alloc) { - free_mem_block (rlcP->receiver_buffer_alloc); - } - - if (rlcP->input_sdus_alloc) { - free_mem_block (rlcP->input_sdus_alloc); - } - - if (rlcP->holes_alloc) { - free_mem_block (rlcP->holes_alloc); - } - - rlcP->holes_alloc = NULL; - rlcP->input_sdus_alloc = NULL; - rlcP->receiver_buffer_alloc = NULL; - rlcP->retransmission_buffer_alloc = NULL; - rlc_am_stop_all_timers (rlcP); -} - -//----------------------------------------------------------------------------- -void -rlc_am_set_configured_parameters (struct rlc_am_entity* rlcP, mem_block_t* cprimitiveP) -{ - //----------------------------------------------------------------------------- - // timers - //rlcP->timer_poll_trigger = ((struct crlc_primitive *)cprimitiveP->data)->cprimitive.c_config_req.parameters.am_parameters.timer_poll; - //rlcP-> = ((struct crlc_primitive *)cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.timer_poll_prohibit; - rlcP->timer_discard_init = ((struct crlc_primitive*) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.timer_discard; - rlcP->timer_poll_periodic_init = ((struct crlc_primitive*) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.timer_poll_periodic; - rlcP-> timer_status_prohibit = ((struct crlc_primitive*)cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.timer_status_prohibit; - rlcP->timer_status_periodic = ((struct crlc_primitive*) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.timer_status_periodic; - rlcP->timer_rst_init = ((struct crlc_primitive*) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.timer_rst; - rlcP->max_rst = ((struct crlc_primitive*) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.max_rst; - rlcP->timer_mrw_init = ((struct crlc_primitive*) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.timer_mrw; - // protocol_parameters - rlcP->pdu_size = (((struct crlc_primitive*) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.pdu_size + 7) >> 3; - rlcP->max_dat = ((struct crlc_primitive*) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.max_dat; - rlcP->missing_pdu_indicator = ((struct crlc_primitive*) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.missing_pdu_indicator; - rlcP->poll_pdu_trigger = ((struct crlc_primitive*) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.poll_pdu; - rlcP->poll_sdu_trigger = ((struct crlc_primitive*) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.poll_sdu; - rlcP->last_transmission_pdu_poll_trigger = ((struct crlc_primitive*) - cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.last_transmission_pdu_poll_trigger; - rlcP->last_retransmission_pdu_poll_trigger = ((struct crlc_primitive*) - cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.last_retransmission_pdu_poll_trigger; - rlcP->poll_window_trigger = ((struct crlc_primitive*) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.poll_window; - rlcP->configured_tx_window_size = ((struct crlc_primitive*) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.configured_tx_window_size; - rlcP->configured_rx_window_size = ((struct crlc_primitive*) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.configured_rx_window_size; - rlcP->max_mrw = ((struct crlc_primitive*) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.max_mrw; - rlcP->sdu_discard_mode = ((struct crlc_primitive*) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.sdu_discard_mode; - rlcP->send_mrw = ((struct crlc_primitive*) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.send_mrw; - // SPARE : not 3GPP - rlcP->rb_id = ((struct crlc_primitive*) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.rb_id; - rlcP->frame_tick_milliseconds = ((struct crlc_primitive*) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.frame_tick_milliseconds; - rlcP->nb_logical_channels_per_rlc =1; - - if (rlcP->pdu_size > 126) { - rlcP->rlc_segment = rlc_am_segment_15; - - } else { - rlcP->rlc_segment = rlc_am_segment_7; - } - - if (rlcP->sdu_discard_mode == SDU_DISCARD_MODE_RESET) { - msg ("[RLC AM][RB %d] SDU DISCARD RESET CONFIGURED\n", rlcP->rb_id); - - } else if (rlcP->sdu_discard_mode == SDU_DISCARD_MODE_TIMER_BASED_EXPLICIT) { - msg ("[RLC AM][RB %d] SDU DISCARD TIMER BASED EXPLICIT SIGNALING CONFIGURED\n", rlcP->rb_id); - - } else if (rlcP->sdu_discard_mode == SDU_DISCARD_MODE_MAX_DAT_RETRANSMISSION) { - msg ("[RLC AM][RB %d] SDU DISCARD MAX RETRANSMISSION CONFIGURED\n", rlcP->rb_id); - - } else if (rlcP->sdu_discard_mode == SDU_DISCARD_MODE_NOT_CONFIGURED) { - msg ("[RLC AM][RB %d] SDU DISCARD NOT CONFIGURED\n", rlcP->rb_id); - } -} diff --git a/openair2/LAYER2/RLC/AM/rlc_am_control_primitives_proto_extern.h b/openair2/LAYER2/RLC/AM/rlc_am_control_primitives_proto_extern.h deleted file mode 100755 index 4bf6c0534aa07320c923713663d2326394fdd1f6..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_control_primitives_proto_extern.h +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_control_primitives_proto_extern.h - - ------------------- - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - ***************************************************************************/ -# ifndef __RLC_AM_CONTROL_PRIMITIVES_H__ -# define __RLC_AM_CONTROL_PRIMITIVES_H__ -//----------------------------------------------------------------------------- -# include "rlc_am_entity.h" -# include "mem_block.h" -# include "rrm_config_structs.h" -//----------------------------------------------------------------------------- -extern void config_req_rlc_am (struct rlc_am_entity *rlcP, module_id_t module_idP, rlc_am_info_t * config_amP, uint8_t rb_idP, rb_type_t rb_typeP); -extern void send_rlc_am_control_primitive (struct rlc_am_entity *rlcP, module_id_t module_idP, mem_block_t * cprimitiveP); -extern void init_rlc_am (struct rlc_am_entity *rlcP); -extern void rlc_am_reset_state_variables (struct rlc_am_entity *rlcP); -extern void rlc_am_alloc_buffers_after_establishment (struct rlc_am_entity *rlcP); -extern void rlc_am_discard_all_pdus (struct rlc_am_entity *rlcP); -extern void rlc_am_stop_all_timers (struct rlc_am_entity *rlcP); -extern void rlc_am_free_all_resources (struct rlc_am_entity *rlcP); -extern void rlc_am_set_configured_parameters (struct rlc_am_entity *rlcP, mem_block_t * cprimitiveP); -//extern void rlc_am_probing_get_buffer_occupancy_measurements (struct rlc_am_entity *rlcP, probing_report_traffic_rb_parameters *reportP, int measurement_indexP); -# endif diff --git a/openair2/LAYER2/RLC/AM/rlc_am_demux.c b/openair2/LAYER2/RLC/AM/rlc_am_demux.c deleted file mode 100755 index 671d65153ac1845fe4a0e1f39ffd0272956e83d8..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_demux.c +++ /dev/null @@ -1,223 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_demux.c - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - ***************************************************************************/ -#include "rtos_header.h" -#include "platform_types.h" -//----------------------------------------------------------------------------- -//#include "mac_log_interface_struct.h" -#include "LAYER2/RLC/rlc.h" - -#include "mac_primitives.h" -#include "list.h" -#include "rlc_am_entity.h" -#include "rlc_am_structs.h" -#include "rlc_am_constants.h" -#include "rlc_am_receiver_proto_extern.h" -#include "rlc_am_reset_proto_extern.h" -#include "rlc_am_status_proto_extern.h" -#include "rlc_am_timers_proto_extern.h" -#include "LAYER2/MAC/extern.h" - - - -#define DEBUG_DEMUX_RESET -#define DEBUG_DEMUX - -//----------------------------------------------------------------------------- -void -rlc_am_demux_routing (struct rlc_am_entity *rlcP, unsigned int traffic_typeP, struct mac_data_ind data_indP) -{ - //----------------------------------------------------------------------------- - - struct rlc_am_pdu_header *data; - struct rlc_am_reset_header *control; - mem_block_t *tb; - uint8_t *first_byte; - uint16_t tb_size_in_bytes; - uint8_t first_bit; - uint8_t bits_to_shift; - uint8_t bits_to_shift_last_loop; - - uint8_t data_received; - int index; - - //------------------------------------------------------- - // D A T A P D U - //------------------------------------------------------- - data_received = 0; - - while ((tb = list_remove_head (&data_indP.data))) { - if (!(((struct mac_tb_ind *) (tb->data))->error_indication)) { - - first_byte = ((struct mac_tb_ind *) (tb->data))->data_ptr; - - tb_size_in_bytes = data_indP.tb_size >> 3; - first_bit = ((struct mac_tb_ind *) (tb->data))->first_bit; - - if (first_bit > 0) { - // shift data of transport_block TO CHECK - bits_to_shift_last_loop = 0; - - while ((tb_size_in_bytes)) { - bits_to_shift = first_byte[tb_size_in_bytes] >> (8 - first_bit); - first_byte[tb_size_in_bytes] = (first_byte[tb_size_in_bytes] << first_bit) | (bits_to_shift_last_loop); - tb_size_in_bytes -= 1; - bits_to_shift_last_loop = bits_to_shift; - } - - first_byte[0] = (first_byte[0] << first_bit) | (bits_to_shift_last_loop); - } - - ((struct rlc_am_rx_pdu_management *) (tb->data))->first_byte = first_byte; - data = (struct rlc_am_pdu_header *) (first_byte); - - if ((data->byte1 & RLC_DC_MASK) == RLC_DC_DATA_PDU) { -#ifdef DEBUG_DEMUX - msg ("[RLC_AM][RB %d][DEMUX] RX AMD PDU Frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame); - - for (index=0; index < rlcP->pdu_size ; index++) { - msg("%02X.",first_byte[index]); - } - - msg("\n"); -#endif - - rlcP->stat_rx_data_pdu += 1; - - if (traffic_typeP & RLC_AM_TRAFFIC_ALLOWED_FOR_DATA) { - ((struct rlc_am_rx_pdu_management *) (tb->data))->piggybacked_processed = 0; - receiver_retransmission_management (rlcP, tb, data); - // pdu is data; - data_received = 1; - } else { -#ifdef DEBUG_DEMUX - msg ("[RLC_AM][RB %d][DEMUX] DROP DATA TB NOT ALLOWED IN PROTOCOL STATE 0x%02X\n", rlcP->rb_id, rlcP->protocol_state); -#endif - free_mem_block (tb); - } - - } else { - rlcP->stat_rx_control_pdu += 1; - control = (struct rlc_am_reset_header *) first_byte; - - if ((control->byte1 & RLC_PDU_TYPE_MASK) == RLC_PDU_TYPE_STATUS) { - if (traffic_typeP & RLC_AM_TRAFFIC_ALLOWED_FOR_DATA) { -#ifdef DEBUG_DEMUX - msg ("[RLC_AM][RB %d][DEMUX] RX STATUS PDU ON DTCH Frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame); -#endif - rlc_am_process_status_info (rlcP, &(control->byte1)); - } - } else if ((control->byte1 & RLC_PDU_TYPE_MASK) == RLC_PDU_TYPE_RESET) { -#ifdef DEBUG_DEMUX_RESET - msg ("[RLC_AM][RB %d][DEMUX] RX RESET PDU Frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame); -#endif - process_reset (tb, control, rlcP); - } else if ((control->byte1 & RLC_PDU_TYPE_MASK) == RLC_PDU_TYPE_RESET_ACK) { -#ifdef DEBUG_DEMUX_RESET - msg ("[RLC_AM][RB %d][DEMUX] RX RESET ACK PDU Frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame); -#endif - process_reset_ack (tb, control, rlcP); -#ifndef USER_MODE - rlc_info_t Rlc_info_am_config1; - - Rlc_info_am_config1.rlc_mode=RLC_AM; - Rlc_info_am_config1.rlc.rlc_am_info.sdu_discard_mode = SDU_DISCARD_MODE_RESET;//SDU_DISCARD_MODE_MAX_DAT_RETRANSMISSION;// - Rlc_info_am_config1.rlc.rlc_am_info.timer_poll = 0; - Rlc_info_am_config1.rlc.rlc_am_info.timer_poll_prohibit = 0; - Rlc_info_am_config1.rlc.rlc_am_info.timer_discard = 500; - Rlc_info_am_config1.rlc.rlc_am_info.timer_poll_periodic = 0; - Rlc_info_am_config1.rlc.rlc_am_info.timer_status_prohibit = 250; - Rlc_info_am_config1.rlc.rlc_am_info.timer_status_periodic = 500; - Rlc_info_am_config1.rlc.rlc_am_info.timer_rst = 250;//250 - Rlc_info_am_config1.rlc.rlc_am_info.max_rst = 500;//500 - Rlc_info_am_config1.rlc.rlc_am_info.timer_mrw = 0; - - Rlc_info_am_config1.rlc.rlc_am_info.pdu_size = 32; //416; // in bits - //Rlc_info_am.rlc.rlc_am_info.in_sequence_delivery = 1;//boolean - Rlc_info_am_config1.rlc.rlc_am_info.max_dat = 32;//127; - - Rlc_info_am_config1.rlc.rlc_am_info.poll_pdu = 0; - Rlc_info_am_config1.rlc.rlc_am_info.poll_sdu = 0;//256;/ - - - - Rlc_info_am_config1.rlc.rlc_am_info.poll_window = 80;//128 - Rlc_info_am_config1.rlc.rlc_am_info.tx_window_size = 512; - Rlc_info_am_config1.rlc.rlc_am_info.rx_window_size = 512; - - - Rlc_info_am_config1.rlc.rlc_am_info.max_mrw = 8; - - Rlc_info_am_config1.rlc.rlc_am_info.last_transmission_pdu_poll_trigger = 1;//boolean - Rlc_info_am_config1.rlc.rlc_am_info.last_retransmission_pdu_poll_trigger = 1;//boolean - Rlc_info_am_config1.rlc.rlc_am_info.send_mrw = 1;//boolean* - Mac_rlc_xface->rrc_rlc_config_req(0,CONFIG_ACTION_REMOVE,rlcP->rb_id,RADIO_ACCESS_BEARER,Rlc_info_am_config1); - Mac_rlc_xface->rrc_rlc_config_req(0,CONFIG_ACTION_ADD,rlcP->rb_id,RADIO_ACCESS_BEARER,Rlc_info_am_config1); - -#endif - } - - free_mem_block (tb); - } - } else { -#ifdef BENCH_QOS_L2 - fprintf (bench_l2, "[PDU RX ERROR] FRAME %d RLC-AM %p\n", Mac_rlc_xface->frame, rlcP); -#endif -#ifdef DEBUG_DEMUX - msg ("[RLC_AM][RB %d][DEMUX] RX PDU WITH ERROR INDICATION\n", rlcP->rb_id); -#endif - rlcP->stat_rx_error_pdu += 1; - free_mem_block (tb); - } - } - - if ((data_received)) { //avoid call - if (traffic_typeP & RLC_AM_TRAFFIC_ALLOWED_FOR_DATA) { - if (rlcP->pdu_size <= 126) { -#ifdef DEBUG_DEMUX - msg("[RLC_AM][RB %d] Calling process_receiver_buffer_7\n",rlcP->rb_id); -#endif - process_receiver_buffer_7 (rlcP); - } else { -#ifdef DEBUG_DEMUX - msg("[RLC_AM][RB %d] Calling process_receiver_buffer_15\n",rlcP->rb_id); -#endif - process_receiver_buffer_15 (rlcP); - } - } - } -} diff --git a/openair2/LAYER2/RLC/AM/rlc_am_demux_proto_extern.h b/openair2/LAYER2/RLC/AM/rlc_am_demux_proto_extern.h deleted file mode 100755 index 60a0e68236d461544fada4e15a7a7e5d70c1bc9f..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_demux_proto_extern.h +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_demux_proto_extern.h - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - ***************************************************************************/ -# ifndef __RLC_AM_DEMUX_PROTO_EXTERN_H__ -# define __RLC_AM_DEMUX_PROTO_EXTERN_H__ -//----------------------------------------------------------------------------- -# include "rlc_am_entity.h" -# include "mac_primitives.h" -//----------------------------------------------------------------------------- -extern void rlc_am_demux_routing (struct rlc_am_entity *rlcP, unsigned int traffic_typeP, struct mac_data_ind data_indP); -# endif diff --git a/openair2/LAYER2/RLC/AM/rlc_am_discard_notif.c b/openair2/LAYER2/RLC/AM/rlc_am_discard_notif.c deleted file mode 100755 index 5955284e88fb35c761e6ca50612f65e466d687fe..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_discard_notif.c +++ /dev/null @@ -1,405 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_discard_notif.c - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - ***************************************************************************/ -#define RLC_AM_C -#include "rtos_header.h" -#include "platform_types.h" -//----------------------------------------------------------------------------- -#include "rlc.h" -#include "rlc_primitives.h" -#include "rlc_am_status_proto_extern.h" -#include "umts_timer_struct.h" -#include "umts_timer_proto_extern.h" -#include "rlc_am_discard_tx_proto_extern.h" -#include "rlc_am_reset_proto_extern.h" -#include "LAYER2/MAC/extern.h" -//----------------------------------------------------------------------------- -void rlc_am_discard_notify_mrw_ack_time_out (struct rlc_am_entity* rlcP, mem_block_t* discard_procedureP); -void rlc_am_discard_notify_sdu_time_out (struct rlc_am_entity* rlcP, mem_block_t* sduP); -void rlc_am_discard_notify_max_dat_pdu (struct rlc_am_entity* rlcP, mem_block_t* mbP); -//----------------------------------------------------------------------------- -// handler for timer -//----------------------------------------------------------------------------- -void -rlc_am_discard_notify_mrw_ack_time_out (struct rlc_am_entity* rlcP, mem_block_t* discard_procedureP) -{ - //----------------------------------------------------------------------------- - /* from 3GPP TS 25.322 V5.5.0 - If Timer_MRW expires before the discard procedure is terminated, the Sender shall: - - if VT(MRW)<MaxMRW-1: - - set the MRW SUFI as previously transmitted (even if additional SDUs were discarded in the mean-time); - - include the MRW SUFI in a new status report (if other SUFIs are included, their contents shall be updated); - - transmit the status report by either including it in a STATUS PDU or piggybacked in an AMD PDU; - - increment VT(MRW) by one; - - restart Timer_MRW for this discard procedure. - - If the number of retransmission of an MRW SUFI (i.e. VT(MRW)) equals MaxMRW, the Sender shall: - - terminate the SDU discard with explicit signalling procedure; - - stop the timer Timer_MRW; - - deliver an error indication to upper layers; - - initiate the RLC RESET procedure */ - rlcP->timer_mrw = NULL; -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d][DISCARD] NOTIF MRW_ACK TIME OUT VT(MRW) %d PROCEDURE %p\n", rlcP->rb_id, rlcP->vt_mrw, discard_procedureP); -#endif - - if ((rlcP->protocol_state & (RLC_RESET_PENDING_STATE | RLC_RESET_AND_SUSPEND_STATE)) == 0) { - // check the number of retransmission of the status pdu - if (rlcP->vt_mrw < (rlcP->max_mrw - 1)) { - rlc_am_schedule_procedure (rlcP); -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM %p][DISCARD] NOTIF MRW_ACK TIME OUT REARM TIMER\n", rlcP); -#endif - rlcP->vt_mrw += 1; - - } else { - // TO DO : "deliver an error indication to upper layers" -#ifdef DEBUG_RESET - msg ("\n[RLC_AM][RB %d][DISCARD] NOTIF MRW_ACK TIME OUT MAX_MRW REACHED -> RESET\n", rlcP->rb_id); -#endif - send_reset_pdu (rlcP); - } - } -} - -// handler for timer -//----------------------------------------------------------------------------- -void -rlc_am_discard_check_sdu_time_out (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - mem_block_t* sdu; - mem_block_t* pdu; - int discard_go_on; - int last_removed_pdu_sn; - int sn; - - // TIMER BASED DISCARD - if ((rlcP->sdu_discard_mode & RLC_SDU_DISCARD_TIMER_BASED_EXPLICIT) - && ((rlcP->protocol_state & (RLC_RESET_PENDING_STATE | RLC_RESET_AND_SUSPEND_STATE)) == 0)) { - /* from 3GPP TS 25.322 V5.0.0 p68 - - if "Timer based SDU discard with explicit signalling" is configured: - - discard all SDUs up to and including the SDU for which the timer Timer_Discard expired. - - discard all AMD PDUs including segments of the discarded SDUs, unless they also carry a segment of a SDU - whose timer has not expired; - - if more than 15 discarded SDUs are to be informed to the Receiver: - - if "Send MRW" is not configured: - - assemble an MRW SUFI with the discard information of the SDUs. - - otherwise ("Send MRW" is configured): - - assemble an MRW SUFI with the discard information of the first 15 SDUs; and - - include the discard information of the rest SDUs in another MRW SUFI which shall be sent by the next - SDU discard with explicit signalling procedure (after the current SDU discard with explicit signalling - procedure is terminated). - - otherwise (less than or equal to 15 discarded SDUs are to be informed to the Receiver): - - assemble an MRW SUFI with the discard information of the SDUs. - - schedule and submit to lower layer a STATUS PDU/piggybacked STATUS PDU containing the MRW SUFI; - - if SN_MRWLENGTH in the MRW SUFI >VT(S): - - update VT(S) to SN_MRWLENGTH. - - start a timer Timer_MRW - If a new SDU discard with explicit signalling procedure is triggered when the timer Timer_MRW is active, no new - MRW SUFIs shall be sent before the current SDU discard with explicit signalling procedure is terminated by one of the - termination criteria. - */ - discard_go_on = 1; - last_removed_pdu_sn = -1; - - while ((sdu = rlcP->input_sdus[rlcP->current_sdu_index]) && discard_go_on) { - if ((*rlcP->frame_tick_milliseconds - ((struct rlc_am_tx_sdu_management*) (sdu->data))->sdu_creation_time) >= rlcP->timer_discard_init) { - // buffer occupancy is not updated at each generation of pdu, it is only updated for a sdu when the - // segmentation of this one is finished. - rlcP->buffer_occupancy -= ((struct rlc_am_tx_sdu_management*) (sdu->data))->sdu_remaining_size; - rlcP->nb_sdu -= 1; - - if ((rlcP->send_mrw & RLC_AM_SEND_MRW_ON) || - // the condition says if the sdu has generated one or more pdus - (((struct rlc_am_tx_sdu_management*) (sdu->data))->sdu_size != ((struct rlc_am_tx_sdu_management*) (sdu->data))->sdu_remaining_size)) { - ((struct rlc_am_tx_sdu_management*) (sdu->data))->last_pdu_sn = rlcP->vt_s; - ((struct rlc_am_tx_sdu_management*) (sdu->data))->no_new_sdu_segmented_in_last_pdu = 1; - rlcP->vt_s = (rlcP->vt_s + 1) & SN_12BITS_MASK; - list2_add_tail (sdu, &rlcP->sdu_discarded); -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] SDU DISCARDED SIGNALLING YES, TIMED OUT %ld ms frame %d ", rlcP->rb_id, - (*rlcP->frame_tick_milliseconds - ((struct rlc_am_tx_sdu_management*) (sdu->data))->sdu_creation_time), Mac_rlc_xface->frame); - msg ("BO %d, NB SDU %d\n", rlcP->buffer_occupancy, rlcP->nb_sdu); - display_protocol_vars_rlc_am (rlcP); -#endif - - if (((struct rlc_am_tx_sdu_management*) (sdu->data))->sdu_size != ((struct rlc_am_tx_sdu_management*) (sdu->data))->sdu_remaining_size) { - // some pdu have to be removed if a sdu discarded generated almost one pdu - if (last_removed_pdu_sn == -1) { - sn = rlcP->vt_a; - - } else { - sn = last_removed_pdu_sn; - } - - while (sn != rlcP->vt_s) { - pdu = rlcP->retransmission_buffer[sn % rlcP->recomputed_configured_tx_window_size]; - - if ((pdu)) { - // now check if a copy of the pdu is not present in the retransmission_buffer_to_send - if ((((struct rlc_am_tx_data_pdu_management*) (pdu->data))->copy)) { - list2_remove_element (((struct rlc_am_tx_data_pdu_management*) (pdu->data))->copy, &rlcP->retransmission_buffer_to_send); - free_mem_block (((struct rlc_am_tx_data_pdu_management*) (pdu->data))->copy); - } - - // if this pdu has been retransmitted, remove its size from buffer occupancy - if (((struct rlc_am_tx_data_pdu_management*) (pdu->data))->vt_dat > 0) { - rlcP->buffer_occupancy_retransmission_buffer -= 1; - } - - free_mem_block (rlcP->retransmission_buffer[sn % rlcP->recomputed_configured_tx_window_size]); - rlcP->retransmission_buffer[sn % rlcP->recomputed_configured_tx_window_size] = NULL; - } - - sn = (sn + 1) & SN_12BITS_MASK; - } - - last_removed_pdu_sn = sn; - } - - } else { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] SDU DISCARDED SIGNALLING NO, TIMED OUT %ld ms ", rlcP->rb_id, - (*rlcP->frame_tick_milliseconds - ((struct rlc_am_tx_sdu_management*) (sdu->data))->sdu_creation_time)); - msg ("BO %d, NB SDU %d\n", rlcP->buffer_occupancy, rlcP->nb_sdu); -#endif - free_mem_block (sdu); - } - - if (!(rlcP->data_plane)) { -#ifdef DEBUG_RLC_AM_SEND_CONFIRM - msg ("[RLC_AM][RB %d][CONFIRM] SDU MUI %d LOST IN DISCARD\n", rlcP->rb_id, - ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[rlcP->current_sdu_index]->data))->mui); -#endif - rlc_data_conf (0, rlcP->rb_id, ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[rlcP->current_sdu_index]->data))->mui, RLC_TX_CONFIRM_FAILURE, - rlcP->data_plane); - } - - rlcP->input_sdus[rlcP->current_sdu_index] = NULL; - rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % rlcP->size_input_sdus_buffer; - // reset variables for segmentation - rlcP->li_exactly_filled_to_add_in_next_pdu = 0; - rlcP->li_one_byte_short_to_add_in_next_pdu = 0; - - } else { - discard_go_on = 0; - } - } - } -} - -//----------------------------------------------------------------------------- -void -rlc_am_discard_notify_max_dat_pdu (struct rlc_am_entity* rlcP, mem_block_t* pduP) -{ - //----------------------------------------------------------------------------- - struct rlc_am_tx_data_pdu_management* pdu_mngt; - struct rlc_am_tx_sdu_management* sdu_mngt; - mem_block_t* pdu; - mem_block_t* pdu2; - mem_block_t* sdu; - int sdu_index; - int sdu_index2; - int pdu_index; - int last_sdu_index; - int sn; - pdu_mngt = (struct rlc_am_tx_data_pdu_management*) pduP->data; - // should never occur - //if (pdu_mngt->nb_sdu == 0) return; - // discard previous SDUS -#ifdef DEBUG_RLC_AM_DISCARD_MAX_DAT - msg ("[RLC_AM][RB %d] DISCARD MAX DAT PDU FRAME %d SN 0x%03X CONTAINS SDU INDEX ", rlcP->rb_id, Mac_rlc_xface->frame, pdu_mngt->sn); - sdu_index = 0; - - while (sdu_index < pdu_mngt->nb_sdu) { - msg ("%d ", pdu_mngt->sdu[sdu_index]); - sdu_index += 1; - } - - msg ("\n"); -#endif - // From 3GPP TS25.322 V5.0.0 (2002-03) page 68 - // - if "SDU discard after MaxDAT number of retransmissions" is configured: - // - discard all SDUs that have segments in AMD PDUs with SN inside the interval - // VT(A) <= SN <= X, where X is the value of the SN of the AMD PDU with VT(DAT) >= MaxDAT; - // - if requested - // - inform the upper layers of the discarded SDUs. - //--------------------------------------------------------------- - // here delete all SDUs before the last sdu that have segments in the pdu discarded - sdu_index = rlcP->next_sdu_index; - last_sdu_index = pdu_mngt->sdu[pdu_mngt->nb_sdu - 1]; - - while (sdu_index != last_sdu_index) { - if ((sdu = rlcP->input_sdus[sdu_index])) { - list2_add_tail (sdu, &rlcP->sdu_discarded); - - if (!(rlcP->data_plane)) { -#ifdef DEBUG_RLC_AM_SEND_CONFIRM - msg ("[RLC_AM][RB %d][CONFIRM] SDU MUI %d LOST IN DISCARD\n", rlcP->rb_id, ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[sdu_index]->data))->mui); -#endif - rlc_data_conf (0, rlcP->rb_id, ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[sdu_index]->data))->mui, RLC_TX_CONFIRM_FAILURE, rlcP->data_plane); - } - - rlcP->input_sdus[sdu_index] = NULL; - rlcP->nb_sdu -= 1; -#ifdef DEBUG_RLC_AM_FREE_SDU - msg ("[RLC_AM][RB %d] DISCARD MAX DAT FREE_SDU INDEX %d\n", rlcP->rb_id, sdu_index); -#endif - } - - sdu_index = (sdu_index + 1) % rlcP->size_input_sdus_buffer; - } - - //--------------------------------------------------------------- - // here delete all PDUs up to and except the last of the last sdu discarded - sdu = rlcP->input_sdus[sdu_index]; - sdu_mngt = (struct rlc_am_tx_sdu_management*) (sdu->data); - sn = rlcP->vt_a; - - while (sn != sdu_mngt->last_pdu_sn) { - if ((pdu2 = rlcP->retransmission_buffer[sn % rlcP->recomputed_configured_tx_window_size])) { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD FREE PDU SN 0x%03X\n", rlcP->rb_id, sn); -#endif - - // check if a copy of the pdu is not present in the retransmission_buffer_to_send - if ((((struct rlc_am_tx_data_pdu_management*) (pdu2->data))->copy)) { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] FREE PDU COPY ALSO\n", rlcP->rb_id); -#endif - list2_remove_element (((struct rlc_am_tx_data_pdu_management*) (pdu2->data))->copy, &rlcP->retransmission_buffer_to_send); - free_mem_block (((struct rlc_am_tx_data_pdu_management*) (pdu2->data))->copy); - } - - // if this pdu has been retransmitted, remove its size from buffer occupancy - if (((struct rlc_am_tx_data_pdu_management*) (pdu2->data))->vt_dat > 0) { - rlcP->buffer_occupancy_retransmission_buffer -= 1; - } - - free_mem_block (pdu2); - rlcP->retransmission_buffer[sn % rlcP->recomputed_configured_tx_window_size] = NULL; - } - - sn = (sn + 1) & SN_12BITS_MASK; - } - - //---------------------------------------------- - // Now for the last pdu of the last sdu discarded, check if it contains other segments of - // sdu newer than the discarded - // if the pdu cannot be found : it is OK, nothing to do - pdu = rlcP->retransmission_buffer[sdu_mngt->last_pdu_sn % rlcP->recomputed_configured_tx_window_size]; - - if ((pdu)) { - // search the index of the sdu passed in parameter - pdu_mngt = (struct rlc_am_tx_data_pdu_management*) pdu->data; - - if (pdu_mngt->sdu[pdu_mngt->nb_sdu - 1] == sdu_index) { - //---------------------------------------------- - // now check if a copy of the pdu is not present in the retransmission_buffer_to_send - if ((pdu_mngt->copy)) { - list2_remove_element (pdu_mngt->copy, &rlcP->retransmission_buffer_to_send); - free_mem_block (pdu_mngt->copy); - } - -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD LAST PDU SN 0x%03X\n", rlcP->rb_id, sn); - rlc_am_display_data_pdu7 (pdu); -#endif - - //---------------- - // discard the pdu - // if this pdu has been retransmitted, remove its size from buffer occupancy - if (((struct rlc_am_tx_data_pdu_management*) (pdu->data))->vt_dat > 0) { - rlcP->buffer_occupancy_retransmission_buffer -= 1; - } - - pdu_index = pdu_mngt->sn % rlcP->recomputed_configured_tx_window_size; - free_mem_block (rlcP->retransmission_buffer[pdu_index]); - rlcP->retransmission_buffer[pdu_index] = NULL; - - } else { - // if this pdu is not discarded, mark the sdu discarded by writing "-1" for their index : used in retransmission -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD LAST PDU SN 0x%03X, CONTAINS OTHER SDUS (LAST SDU INDEX=%d): NOT CLEARED\n", rlcP->rb_id, sdu_mngt->last_pdu_sn, - pdu_mngt->sdu[pdu_mngt->nb_sdu - 1]); -#endif - sdu_index2 = 0; - - while (pdu_mngt->sdu[sdu_index2] != sdu_index) { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD LAST PDU SN 0x%03X, MARK SDU index % AS DISCARDED\n", rlcP->rb_id, pdu_mngt->sn, pdu_mngt->sdu[sdu_index2]); -#endif - pdu_mngt->sdu[sdu_index2] = -1; - sdu_index2 += 1; - } - -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD LAST PDU SN 0x%03X, MARK SDU index %d AS DISCARDED\n", rlcP->rb_id, pdu_mngt->sn, pdu_mngt->sdu[sdu_index2]); -#endif - pdu_mngt->sdu[sdu_index2] = -1; - } - } - -#ifdef DEBUG_RLC_AM_DISCARD - - else { - msg ("[RLC_AM][RB %d] DISCARD LAST PDU SN 0x%03X, ALREADY CLEARED\n", rlcP->rb_id, sdu_mngt->last_pdu_sn); - } - -#endif - - //---------------- - // discard the sdu - if ((rlcP->input_sdus[sdu_index])) { // may be removed by "free_retransmission_buffer_no_confirmation" - if (sdu_index == rlcP->current_sdu_index) { - // sdu under segmentation - rlcP->buffer_occupancy -= ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[sdu_index]->data))->sdu_remaining_size; - ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[sdu_index]->data))->no_new_sdu_segmented_in_last_pdu = 1; - rlcP->li_exactly_filled_to_add_in_next_pdu = 0; - rlcP->li_one_byte_short_to_add_in_next_pdu = 0; -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD THE SDU DISCARDED WAS UNDER SEGMENTATION (index %d)\n", rlcP->rb_id, sdu_index); -#endif - } - - list2_add_tail (rlcP->input_sdus[sdu_index], &rlcP->sdu_discarded); -#ifdef DEBUG_RLC_AM_FREE_SDU - msg ("[RLC_AM][RB %d] DISCARD MAX DAT FREE_SDU INDEX %d\n", rlcP - rb_id, sdu_index); -#endif - rlcP->input_sdus[sdu_index] = NULL; - rlcP->nb_sdu -= 1; - } -} diff --git a/openair2/LAYER2/RLC/AM/rlc_am_discard_notif_proto_extern.h b/openair2/LAYER2/RLC/AM/rlc_am_discard_notif_proto_extern.h deleted file mode 100755 index f477e81c17a5c698a53830a26d6376613790913d..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_discard_notif_proto_extern.h +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_discard_notif_proto_extern.h - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - ***************************************************************************/ -# ifndef __RLC_AM_DISCARD_NOTIF_PROTO_EXTERN_H__ -# define __RLC_AM_DISCARD_NOTIF_PROTO_EXTERN_H__ -//----------------------------------------------------------------------------- -# include "rlc_am_entity.h" -# include "rlc_am_structs.h" -# include "rlc_am_constants.h" -# include "mem_block.h" -//----------------------------------------------------------------------------- -extern void rlc_am_discard_notify_mrw_ack_time_out (struct rlc_am_entity *rlcP, mem_block_t * discard_procedureP); -extern void rlc_am_discard_check_sdu_time_out (struct rlc_am_entity *rlcP); -extern void rlc_am_discard_notify_max_dat_pdu (struct rlc_am_entity *rlcP, mem_block_t * pduP); -# endif diff --git a/openair2/LAYER2/RLC/AM/rlc_am_discard_rx.c b/openair2/LAYER2/RLC/AM/rlc_am_discard_rx.c deleted file mode 100755 index 7566cfaa171d189bf052bd13313d70e9f34b2837..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_discard_rx.c +++ /dev/null @@ -1,614 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_discard_rx.c - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - ***************************************************************************/ -#include "rtos_header.h" -#include "platform_types.h" -//----------------------------------------------------------------------------- -#include "rlc_am_receiver_proto_extern.h" -#include "rlc_primitives.h" -#include "rlc_am_status_proto_extern.h" -#include "rlc_am_receiver_proto_extern.h" -#include "rlc_am_discard_tx_proto_extern.h" -#include "rlc_am_discard_notif_proto_extern.h" -#include "rlc_am_retrans_proto_extern.h" -#include "rlc_am_util_proto_extern.h" -#include "rlc_am_proto_extern.h" -#include "umts_timer_struct.h" -#include "umts_timer_proto_extern.h" -#include "mem_block.h" -//----------------------------------------------------------------------------- -void rlc_am_received_sufi_ack_check_discard_procedures (struct rlc_am_entity* rlcP); -void rlc_am_free_discard_procedure (mem_block_t* mb_current_procedureP); -inline void rlc_am_discard_free_receiver_buffer (struct rlc_am_entity* rlcP, uint16_t sn_mrw_iP, uint8_t nlengthP); -uint8_t* retransmission_buffer_management_mrw (struct rlc_am_entity* rlcP, uint8_t* byte1P, uint8_t* byte_alignedP); -uint8_t* retransmission_buffer_management_mrw_ack (struct rlc_am_entity* rlcP, uint8_t* byte1P, uint8_t* byte_alignedP); -//----------------------------------------------------------------------------- -void -rlc_am_received_sufi_ack_check_discard_procedures (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - mem_block_t* mb_proc; - mem_block_t* tmp_proc; - struct rlc_am_discard_procedure* procedure; - /* From 3GPP 25.322 V5.0.0 (2002-03) - The Sender shall terminate the SDU discard with explicit signalling procedure if one of the - following criteria is fulfilled: - - - a STATUS PDU/piggybacked STATUS PDU containing an MRW_ACK SUFI is received, and the SN_ACK : DONE in retransmission_buffer_management_mrw_ack(..) - field in the received MRW_ACK SUFI > the SN_MRWLENGTH field in the transmitted MRW_SUFI, - and the N field in the received MRW_ACK SUFI is set equal to "0000"; - - - a STATUS PDU/piggybacked STATUS PDU containing an MRW_ACK SUFI is received, and the SN_ACK : DONE in retransmission_buffer_management_mrw_ack(..) - field in the received MRW_ACK SUFI = the SN_MRWLENGTH field in the transmitted MRW_SUFI, - and the N field in the received MRW_ACK SUFI is set equal to the NLENGTH field in the - transmitted MRW SUFI; - - - a STATUS PDU/piggybacked STATUS PDU containing an ACK SUFI is received, and the LSN field : DONE HERE - in the received ACK SUFI > the SN_MRWLENGTH field in the transmitted MRW SUFI. - - Upon termination of the SDU discard with explicit signalling procedure, the Sender shall: - - stop the timer Timer_MRW; - - update VT(A) and VT(MS) according to the received STATUS PDU/piggybacked STATUS PDU; - The Sender shall not confirm to upper layers the SDUs that are requested to be discarded. - */ - mb_proc = rlcP->discard_procedures.head; - - while ((mb_proc)) { - procedure = (struct rlc_am_discard_procedure*) (mb_proc->data); - - if (rlc_am_comp_sn (rlcP, rlcP->vt_a, rlcP->vt_a, procedure->last_pdu_sn) > 0) { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD TRANSMIT NEW VT(A) 0x%04X REMOVE PROCEDURE SN_MRWlength 0x%04X\n", rlcP->rb_id, rlcP->vt_a, procedure->last_pdu_sn); - msg ("[RLC_AM][RB %d] DISCARD TRANSMIT ACK\n", rlcP->rb_id); -#endif - tmp_proc = mb_proc->next; - list2_remove_element (mb_proc, &rlcP->discard_procedures); - - // if procedure is running, free timer resources - if ((procedure->running) && (rlcP->timer_mrw)) { - if (rlcP->timer_mrw == list2_remove_element (rlcP->timer_mrw, &rlcP->rlc_am_timer_list)) { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD TRANSMIT ACK->TERMINATE PROCEDURE: REMOVE TIMER mrw id %p\n", rlcP->rb_id, - ((struct timer_unit*) (rlcP->timer_mrw->data))->timer_id); -#endif - free_mem_block (rlcP->timer_mrw); - rlcP->timer_mrw = NULL; - - } else { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD TRANSMIT REMOVE TIMER FAILED\n", rlcP->rb_id); -#endif - } - } - - rlc_am_free_discard_procedure (mb_proc); - mb_proc = tmp_proc; - rlcP->vt_mrw = 0; - - } else { - mb_proc = mb_proc->next; - } - } - - // may be other discard procedures to run - rlc_am_schedule_procedure (rlcP); -} - -//----------------------------------------------------------------------------- -void -rlc_am_free_discard_procedure (mem_block_t* mb_current_procedureP) -{ - //----------------------------------------------------------------------------- - // be carefull : the timer is not free here, it should be done before - struct rlc_am_discard_procedure* procedure; - - if (mb_current_procedureP) { - procedure = (struct rlc_am_discard_procedure*) (mb_current_procedureP->data); - list_free (&procedure->sdu_list); - - if (procedure->control_pdu) { - free_mem_block (procedure->control_pdu); - } - - free_mem_block (mb_current_procedureP); - } -} - -//----------------------------------------------------------------------------- -inline void -rlc_am_discard_free_receiver_buffer (struct rlc_am_entity* rlcP, uint16_t sn_mrw_iP, uint8_t nlengthP) -{ - //----------------------------------------------------------------------------- - uint16_t working_sn; - uint16_t working_sn_index; // index in buffer - // should start reassembly with sn working_sn - working_sn = rlcP->last_reassemblied_sn; - working_sn_index = working_sn % rlcP->recomputed_configured_rx_window_size; -#ifdef DEBUG_RLC_AM_DISCARD - display_receiver_buffer (rlcP); -#endif - - while (working_sn != sn_mrw_iP) { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD RECEIVER FREE RECEIVER BUFFER pdu sn 0x%04X VR(R) 0x%04X\n", rlcP->rb_id, working_sn, rlcP->vr_r); -#endif - free_receiver_buffer (rlcP, working_sn_index); - rlcP->last_reassemblied_sn = working_sn; - working_sn = (working_sn + 1) & SN_12BITS_MASK; - working_sn_index = working_sn % rlcP->recomputed_configured_rx_window_size; - } - - // From 3GPP TS 25.322 V5.0.0 (2002-03) page 35 - // NLENGTH is used together with SN_MRWLENGTH to indicate the end of the last SDU to be discarded in the receiver. - // NLENGTH indicates which LI in the PDU with sequence number SN_MRWLENGTH corresponds to the last SDU to be discarded in the receiver. - // NLENGTH = 0 indicates that the last SDU ended in the PDU with sequence number SN_MRWLENGTH -1 and that the first data octet - // in the PDU with sequence number SN_MRWLENGTH is the first data octet to be reassembled next. - // erase previous sdu in construction - rlcP->output_sdu_size_to_write = 0; - - if ((nlengthP)) { - rlcP->discard_reassembly_after_li = nlengthP; // will be used by process_receiver_buffer - - } else { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD RECEIVER rlc_am_discard_free_receiver_buffer pdu sn 0x%04X (nlength=0)\n", rlcP->rb_id, working_sn); -#endif - free_receiver_buffer (rlcP, working_sn_index); - rlcP->discard_reassembly_after_li = RLC_AM_DISCARD_REASSEMBLY_AT_LI_INDEX_0; - rlcP->last_reassemblied_sn = working_sn; - } -} - -//----------------------------------------------------------------------------- -uint8_t* -retransmission_buffer_management_mrw (struct rlc_am_entity* rlcP, uint8_t* byte1P, uint8_t* byte_alignedP) -{ - //----------------------------------------------------------------------------- - mem_block_t* mb; - uint8_t* p8; - uint16_t sn_mrw_i[15]; - uint16_t new_vr_r; - uint16_t working_sn; - uint16_t working_sn_index; // index in buffer - uint8_t sn_mrw_i_index; - uint8_t mrw_length; - uint8_t nlength; -#ifdef DEBUG_RLC_AM_DISCARD - uint8_t i; -#endif - /* From 3GPP TS 25.322 V5.0.0 (2002-03) - Upon reception of the STATUS PDU/piggybacked STATUS PDU containing an MRW SUFI, the Receiver shall: - - if the LENGTH field in the received MRW SUFI is "0000": - - consider SN_MRW1 to be above or equal to VR(R). - - otherwise: - - consider SN_MRW1 to be less than VR(MR); - - consider all the SN_MRWis other than SN_MRW1 to be in sequential order within the list and - sequentially above or equal to SN_MRWi-1. - - discard AMD PDUs up to and including the PDU with sequence number SN_MRWLENGTH-1; - - if the NLENGTH field in the received MRW SUFI is "0000": - - reassemble from the first data octet of the AMD PDU with sequence number SN_MRWLENGTH - after the discard. - - otherwise: - - discard further the data octets in the AMD PDU with sequence number SN_MRWLENGTH up to and - including the octet indicated by the NLENGTH:th LI field of the PDU with sequence number - SN_MRWLENGTH; - - reassemble from the succeeding data octet in the AMD PDU with sequence number SN_MRWLENGTH - after the discard; - - if "Send MRW" is configured: - - inform upper layers about all of the discarded SDUs that were not previously delivered to - upper layer or discarded by other MRW SUFIs; - - update the state variables VR(R), VR(H) and VR(MR) according to the received - STATUS PDU/piggybacked STATUS PDU; - - assemble a MRW_ACK SUFI - - schedule and submit to lower layer a STATUS PDU/piggybacked STATUS PDU containing the MRW_ACK - SUFI. - - The Receiver shall: - - set the SN_ACK field in the MRW_ACK SUFI to the new value of VR(R), updated after reception - of the MRW SUFI; - - if the SN_ACK field in the MRW_ACK SUFI is set equal to the SN_MRWLENGTH field in the - received MRW SUFI: - - set the N field in the MRW_ACK SUFI to the NLENGTH field in the received MRW SUFI. - - otherwise: - - set the N field in the MRW_ACK SUFI to "0000"; - - include the MRW_ACK SUFI in the next STATUS PDU/piggybacked STATUS PDU to be transmitted, - according to subclause 11.5.2. - */ - p8 = byte1P; - sn_mrw_i_index = 0; - - if (*byte_alignedP) { - mrw_length = *p8++ & 0X0F; // number of SN_MRWi - - } else { - p8 = p8 + 1; - mrw_length = (*p8 & 0XF0) >> 4; // number of SN_MRWi - } - - if (!(mrw_length)) { - if (*byte_alignedP) { - // sn_mrw_i is SN_MRW length - sn_mrw_i[0] = (*p8++) << 4; - sn_mrw_i[0] += (*p8) >> 4; - *byte_alignedP = 0; - - } else { - // sn_mrw_i is SN_MRW length - sn_mrw_i[0] = (*p8++) << 8; - sn_mrw_i[0] += *p8++; - nlength = (*p8 & 0xF0) >> 4; - *byte_alignedP = 1; - } - - sn_mrw_i_index += 1; - - } else { - // get all sn_mrw_i - while (mrw_length != sn_mrw_i_index) { - if (*byte_alignedP) { - sn_mrw_i[sn_mrw_i_index] = (*p8++) << 4; - sn_mrw_i[sn_mrw_i_index] += (*p8) >> 4; - *byte_alignedP = 0; - - } else { - sn_mrw_i[sn_mrw_i_index] = ((*p8++) & 0x0F) << 8; - sn_mrw_i[sn_mrw_i_index] += (*p8++); - *byte_alignedP = 1; - } - - sn_mrw_i_index += 1; - } - } - - // get nlength - if (*byte_alignedP) { - nlength = (*p8 & 0xF0) >> 4; - *byte_alignedP = 0; - - } else { - nlength = *p8++ & 0x0F; - *byte_alignedP = 1; - } - -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD RECEIVER RECEIVED MRW LENGTH %d ", rlcP->rb_id, mrw_length); - - for (i = 0; i < sn_mrw_i_index; i++) { - msg ("sn_mrw%d 0x%04X ", i + 1, sn_mrw_i[i]); - } - - msg ("Nlength %d\n", nlength); -#endif - - /******************************************************************** - * M R W D I S C A R D E D * - ********************************************************************/ - /* From 3GPP TS 25.322 V5.0.0 - Reception of obsolete/corrupted MRW SUFI by the Receiver - If the received MRW SUFI contains outdated information about the receiving window - (receiving window already moved further than MRW SUFI is indicating), the Receiver shall: - - discard the MRW SUFI; - - set the SN_ACK field in the MRW_ACK SUFI to the current value of VR(R); - - set the N field in the MRW_ACK SUFI to "0000"; - - include the MRW_ACK SUFI in the next STATUS PDU/piggybacked STATUS PDU to be transmitted. - */ - if (rlc_am_comp_sn (rlcP, rlcP->vr_r, sn_mrw_i[sn_mrw_i_index - 1], rlcP->vr_r) < 0) { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD RECEIVER ERROR received OBSOLETE/CORRUPTED MRW command VR(R) 0x%04X VR(H) 0x%04X VR(MR) 0x%04X SN_MRWlength 0x%04X\n", - rlcP->rb_id, rlcP->vr_r, rlcP->vr_h, rlcP->vr_mr, sn_mrw_i[sn_mrw_i_index - 1]); -#endif - - // send status pdu mrw_ack - if ((mb = rlc_am_create_status_pdu_mrw_ack (rlcP, 0, rlcP->vr_r))) { - list_add_tail_eurecom (mb, &rlcP->control); - } - - return p8; - - } else { - /******************************************************************** - * M R W N O T D I S C A R D E D * - ********************************************************************/ - new_vr_r = sn_mrw_i[sn_mrw_i_index - 1]; - /*********************************** - * DISCARD PDUS IN THE RECEIVER * - ***********************************/ - // should start discard with sn working_sn - working_sn = rlcP->last_reassemblied_sn; - working_sn_index = working_sn % rlcP->recomputed_configured_rx_window_size; - // discard all pdus except the last one -#ifdef DEBUG_RLC_AM_DISCARD - display_receiver_buffer (rlcP); -#endif - - while (working_sn != new_vr_r) { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD RECEIVER FREE RECEIVER BUFFER pdu sn 0x%04X VR(R) 0x%04X\n", rlcP->rb_id, working_sn, rlcP->vr_r); -#endif - free_receiver_buffer (rlcP, working_sn_index); - rlcP->last_reassemblied_sn = working_sn; - working_sn = (working_sn + 1) & SN_12BITS_MASK; - working_sn_index = working_sn % rlcP->recomputed_configured_rx_window_size; - } - - // From 3GPP TS 25.322 V5.0.0 (2002-03) page 35 - // NLENGTH is used together with SN_MRWLENGTH to indicate the end of the last SDU to be discarded in the receiver. - // NLENGTH indicates which LI in the PDU with sequence number SN_MRWLENGTH corresponds to the last SDU to be discarded in the receiver. - // NLENGTH = 0 indicates that the last SDU ended in the PDU with sequence number SN_MRWLENGTH -1 and that the first data octet - // in the PDU with sequence number SN_MRWLENGTH is the first data octet to be reassembled next. - // erase previous sdu in construction - rlcP->output_sdu_size_to_write = 0; - rlcP->discard_reassembly_start_sn = new_vr_r; - rlcP->discard_reassembly_after_li = nlength; // will be used by process_receiver_buffer - - if (rlc_am_comp_sn (rlcP, rlcP->vr_r, new_vr_r, rlcP->vr_r) > 0) { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD RECEIVER... VR(R) : 0x%04X -> 0x%04X (VR(H)=0x%04X)\n", rlcP->rb_id, rlcP->vr_r, new_vr_r, rlcP->vr_h); -#endif - - if (rlc_am_comp_sn (rlcP, rlcP->vr_r, new_vr_r, rlcP->vr_h) > 0) { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD RECEIVER... VR(H) : 0x%04X -> 0x%04X\n", rlcP->rb_id, rlcP->vr_h, new_vr_r); -#endif - rlcP->vr_h = new_vr_r; - } - - rlcP->vr_r = new_vr_r; - rlcP->ack.vr_r_modified = 1; // for status generation - rlcP->vr_mr = (rlcP->vr_r + rlcP->configured_rx_window_size - 1) & SN_12BITS_MASK; - } - - if ((rlcP->send_mrw & RLC_AM_SEND_MRW_ON)) { - //send tu upper layers discarded sdus infos !! - // TO DO !!!!!!!! - } - - if (rlcP->pdu_size <= 126) { - process_receiver_buffer_7 (rlcP); - - } else { - process_receiver_buffer_15 (rlcP); - } - - /* From 3GPP 25.322 V5.0.0 (2002-03) - The Receiver shall: - - set the SN_ACK field in the MRW_ACK SUFI to the new value of VR(R), updated after reception - of the MRW SUFI; - - if the SN_ACK field in the MRW_ACK SUFI is set equal to the SN_MRWLENGTH field in the - received MRW SUFI: - - set the N field in the MRW_ACK SUFI to the NLENGTH field in the received MRW SUFI. - - otherwise: - - set the N field in the MRW_ACK SUFI to "0000"; - - include the MRW_ACK SUFI in the next STATUS PDU/piggybacked STATUS PDU to be transmitted, - according to subclause 11.5.2. */ - if (sn_mrw_i[sn_mrw_i_index - 1] == rlcP->vr_r) { - mb = rlc_am_create_status_pdu_mrw_ack (rlcP, nlength, rlcP->vr_r); - - } else { - mb = rlc_am_create_status_pdu_mrw_ack (rlcP, 0, rlcP->vr_r); - } - - /* SEND STATUS PDU MRW ACK */ - if (mb) { - list_add_tail_eurecom (mb, &rlcP->control); - } - - return p8; - } -} - -//----------------------------------------------------------------------------- -uint8_t* -retransmission_buffer_management_mrw_ack (struct rlc_am_entity* rlcP, uint8_t* byte1P, uint8_t* byte_alignedP) -{ - //----------------------------------------------------------------------------- - mem_block_t* mb; - mem_block_t* mb_current_procedure; - struct rlc_am_tx_data_pdu_management* rlc_header; - struct rlc_am_discard_procedure* procedure; - uint8_t* p8; - uint16_t sn_ack; - uint16_t index; - uint8_t n; // field of mrw_ack sufi - //------------------------------------- - // DECODE SUFI MRW_ACK - //------------------------------------- - p8 = byte1P; - - if (*byte_alignedP) { - n = *p8++ & 0X0F; - // sn_mrw_i is SN_MRW length - sn_ack = (*p8++) << 4; - sn_ack += (*p8) >> 4; - *byte_alignedP = 0; - - } else { - p8 = p8 + 1; - n = (*p8 & 0XF0) >> 4; - // sn_mrw_i is SN_MRW length - sn_ack = ((*p8++) & 0x0F) << 8; - sn_ack += *p8++; - *byte_alignedP = 1; - } - -#ifdef DEBUG_RLC_AM_DISCARD - msg ("\n[RLC_AM][RB %d] DISCARD TRANSMIT RX MRW_ACK N %d SN_ACK 0x%04X VT(A) 0x%04X VT(S) 0x%04X\n", rlcP->rb_id, n, sn_ack, rlcP->vt_a, rlcP->vt_s); - //display_retransmission_buffer(rlcP); -#endif - - // compare to current running procedure - if ((mb_current_procedure = rlcP->discard_procedures.head)) { - procedure = (struct rlc_am_discard_procedure*) (mb_current_procedure->data); -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD TRANSMIT ... procedure->last_pdu_sn 0x%04X procedure->nlength 0x%04X \n", rlcP->rb_id, procedure->last_pdu_sn, - procedure->nlength); -#endif - - /* From 3GPP TS 25.322 V5.0.0 - The Sender shall discard the received MRW_ACK SUFI if one of the following cases occurs: - - - the timer Timer_MRW is not active; - or - - the SN_ACK field in the received MRW_ACK SUFI < the SN_MRWLENGTH field in the transmitted MRW SUFI; - or - - the SN_ACK field in the received MRW_ACK SUFI = the SN_MRWLENGTH field in the transmitted MRW SUFI, - and the N field in the received MRW_ACK SUFI is not equal to the NLENGTH field in the transmitted MRW SUFI; - or - - the SN_ACK field in the received MRW_ACK SUFI > the SN_MRWLENGTH field in the transmitted MRW SUFI, - and the N field in the received MRW_ACK SUFI is not equal to "0000". - */ - if ((rlcP->timer_mrw == NULL) || // if timer_MRW is not active - (rlc_am_comp_sn (rlcP, rlcP->vt_a, procedure->last_pdu_sn, sn_ack) > 0) || - ((rlc_am_comp_sn (rlcP, rlcP->vt_a, procedure->last_pdu_sn, sn_ack) == 0) && (n != procedure->nlength)) || - ((rlc_am_comp_sn (rlcP, rlcP->vt_a, procedure->last_pdu_sn, sn_ack) < 0) && (n != 0))) { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD TRANSMIT ERROR RX OBSOLETE MRW_ACK VT(A) 0x%04X VT(S) 0x%04X SN_MRWlength 0x%04X N %d SN_ACK 0x%04X\n", - rlcP->rb_id, rlcP->vt_a, rlcP->vt_s, procedure->last_pdu_sn, n, sn_ack); -#endif - - } else if ( - /* From 3GPP 25.322 V5.0.0 (2002-03) - The Sender shall terminate the SDU discard with explicit signalling procedure if one of the - following criteria is fulfilled: - - - a STATUS PDU/piggybacked STATUS PDU containing an MRW_ACK SUFI is received, and the SN_ACK : DONE HERE - field in the received MRW_ACK SUFI > the SN_MRWLENGTH field in the transmitted MRW_SUFI, - and the N field in the received MRW_ACK SUFI is set equal to "0000"; - - - a STATUS PDU/piggybacked STATUS PDU containing an MRW_ACK SUFI is received, and the SN_ACK : DONE HERE - field in the received MRW_ACK SUFI = the SN_MRWLENGTH field in the transmitted MRW_SUFI, - and the N field in the received MRW_ACK SUFI is set equal to the NLENGTH field in the - transmitted MRW SUFI; - - - a STATUS PDU/piggybacked STATUS PDU containing an ACK SUFI is received, and the LSN field : DONE in rlc_am_received_sufi_ack_check_discard_procedures(...) - in the received ACK SUFI > the SN_MRWLENGTH field in the transmitted MRW SUFI. - - Upon termination of the SDU discard with explicit signalling procedure, the Sender shall: - - stop the timer Timer_MRW; - - update VT(A) and VT(MS) according to the received STATUS PDU/piggybacked STATUS PDU; - The Sender shall not confirm to upper layers the SDUs that are requested to be discarded. - */ - (rlc_am_comp_sn (rlcP, rlcP->vt_a, sn_ack, procedure->last_pdu_sn) > 0) || ((sn_ack == procedure->last_pdu_sn) && (n == procedure->nlength)) - ) { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD PROCEDURE %p TERMINATED\n", rlcP->rb_id, mb_current_procedure); -#endif - rlcP->vt_mrw = 0; - - // remove timer - if ((rlcP->timer_mrw)) { - if (rlcP->timer_mrw == list2_remove_element (rlcP->timer_mrw, &rlcP->rlc_am_timer_list)) { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD TRANSMIT TERMINATE PROCEDURE: REMOVE TIMER mrw id %p\n", rlcP->rb_id, ((struct timer_unit*) (rlcP->timer_mrw->data))->timer_id); -#endif - free_mem_block (rlcP->timer_mrw); - rlcP->timer_mrw = NULL; - } - -#ifdef DEBUG_RLC_AM_DISCARD - - else { - msg ("[RLC_AM][RB %d] DISCARD TRANSMIT ERROR TERMINATION PROCEDURE : TIMER MRW IS WRONG\n", - rlcP->rb_id); // in fact : no, the lists are not protected against an element that is not inside the list - } - -#endif - } - -#ifdef DEBUG_RLC_AM_DISCARD - - else { - msg ("[RLC_AM][RB %d] DISCARD TRANSMIT ERROR TERMINATION PROCEDURE : NO TIMER MRW WAS FOUND\n", rlcP->rb_id); - } - -#endif - mb_current_procedure = list2_remove_head (&rlcP->discard_procedures); - - //update VT(A) - if (rlc_am_comp_sn (rlcP, rlcP->vt_a, sn_ack, rlcP->vt_a) > 0) { - // free resources that may be in retransmission buffer - while (rlcP->vt_a != sn_ack) { - index = rlcP->vt_a % rlcP->recomputed_configured_tx_window_size; - - if ((mb = rlcP->retransmission_buffer[index])) { - rlc_header = (struct rlc_am_tx_data_pdu_management*) (mb->data); - - if (rlc_header->nb_sdu > 0) { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD TRANSMIT CASE 1 MRW_ACK\n", rlcP->rb_id); -#endif - // the sender of MRW_ACK changed sn_mrw_length to vr_r, so it is normal to free - // pdus that are linked with sdus - free_retransmission_buffer_no_confirmation (rlcP, index); - - } else { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD TRANSMIT CASE 2 MRW_ACK FREE REMAINING RETRANS PDU 0x%04X\n", rlcP->rb_id, rlcP->vt_a); -#endif - - // if this pdu has been retransmitted, remove its size from buffer occupancy - if (rlc_header->vt_dat > 0) { - rlcP->buffer_occupancy_retransmission_buffer -= 1; - } - - free_mem_block (mb); - rlcP->retransmission_buffer[index] = NULL; - } - } - - rlcP->vt_a = (rlcP->vt_a + 1) & SN_12BITS_MASK; - } - -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD TRANSMIT MRW_ACK VT(A) UPDATED 0x%04X VT(S) 0x%04X\n", rlcP->rb_id, rlcP->vt_a, rlcP->vt_s); -#endif - } - - rlc_am_free_discard_procedure (mb_current_procedure); - rlc_am_schedule_procedure (rlcP); - - } else { - msg ("[RLC_AM][RB %d] DISCARD TRANSMIT ERROR RX MRW_ACK CASE NOT TAKEN IN ACCOUNT : NO ACTION !\n", rlcP->rb_id); - } - } - -#ifdef DEBUG_RLC_AM_DISCARD - //display_mem_load(); - //display_retransmission_buffer(rlcP); -#endif - return p8; -} diff --git a/openair2/LAYER2/RLC/AM/rlc_am_discard_rx_proto_extern.h b/openair2/LAYER2/RLC/AM/rlc_am_discard_rx_proto_extern.h deleted file mode 100755 index 9491a2e9adb0900e5415a7ca7f940dad6b34ef30..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_discard_rx_proto_extern.h +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_discard_rx_proto_extern.h - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - ***************************************************************************/ -# ifndef __RLC_AM_DISCARD_RX_PROTO_EXTERN_H__ -# define __RLC_AM_DISCARD_RX_PROTO_EXTERN_H__ -//----------------------------------------------------------------------------- -# include "rlc_am_entity.h" -# include "mem_block.h" -//----------------------------------------------------------------------------- -extern void rlc_am_received_sufi_ack_check_discard_procedures (struct rlc_am_entity *rlcP); -extern void rlc_am_free_discard_procedure (mem_block_t * mb_current_procedureP); -extern inline void rlc_am_discard_free_receiver_buffer (struct rlc_am_entity *rlcP, uint16_t sn_mrw_iP, uint8_t nlengthP); -extern uint8_t *retransmission_buffer_management_mrw (struct rlc_am_entity *rlcP, uint8_t * byte1P, uint8_t * byte_alignedP); -extern uint8_t *retransmission_buffer_management_mrw_ack (struct rlc_am_entity *rlcP, uint8_t * byte1P, uint8_t * byte_alignedP); -# endif diff --git a/openair2/LAYER2/RLC/AM/rlc_am_discard_tx.c b/openair2/LAYER2/RLC/AM/rlc_am_discard_tx.c deleted file mode 100755 index ec3dcfbf8f4ea7c090fe521bbe999a7857bb5e59..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_discard_tx.c +++ /dev/null @@ -1,386 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_discard_tx.c - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - - ***************************************************************************/ -#include "rtos_header.h" -#include "platform_types.h" -//----------------------------------------------------------------------------- -#include "rlc_am_discard_notif_proto_extern.h" -#include "rlc_am_discard_rx_proto_extern.h" -#include "rlc_primitives.h" -#include "rlc_am_status_proto_extern.h" -#include "rlc_am_util_proto_extern.h" -#include "rlc_am_constants.h" -#include "rlc_am_structs.h" -#include "umts_timer_proto_extern.h" -//----------------------------------------------------------------------------- -void rlc_am_schedule_procedure (struct rlc_am_entity* rlcP); -void rlc_am_process_sdu_discarded (struct rlc_am_entity* rlcP); -void rlc_am_sdu_discard_with_explicit_signalling_procedure_send_mrw_configured (struct rlc_am_entity* rlcP); -void rlc_am_sdu_discard_with_explicit_signalling_procedure_send_mrw_not_configured (struct rlc_am_entity* rlcP); -//----------------------------------------------------------------------------- -void -rlc_am_schedule_procedure (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - mem_block_t* pdu_status; - struct rlc_am_discard_procedure* procedure; - - // if a procedure is running do nothing - if (!(rlcP->timer_mrw) && (rlcP->discard_procedures.head)) { - // launch remaining procedures (only 1 procedure running) - procedure = (struct rlc_am_discard_procedure*) ((rlcP->discard_procedures.head)->data); - /* sn_mrw_length = procedure->last_pdu_sn; - - if (rlc_am_comp_sn(rlcP, rlcP->vt_s, sn_mrw_length, rlcP->vt_s) > 0) { - #ifdef DEBUG_RLC_AM_DISCARD - msg("[RLC_AM %p][DISCARD] SCHEDULE PROCEDURE %p UPDATE VT(S) %04X -> %04X\n", rlcP, rlcP->discard_procedures.head, rlcP->vt_s, sn_mrw_length); - #endif - rlcP->vt_s = sn_mrw_length; - } - */ -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD SCHEDULE PROCEDURE %p vt_s 0x%04X vt_a 0x%04X\n", rlcP->rb_id, rlcP->discard_procedures.head, rlcP->vt_s, rlcP->vt_a); -#endif - procedure->running = 0xFF; - pdu_status = get_free_mem_block (rlcP->pdu_size + sizeof (struct rlc_am_tx_control_pdu_allocation) + GUARD_CRC_LIH_SIZE); - memcpy (pdu_status->data, procedure->control_pdu->data, rlcP->pdu_size + sizeof (struct rlc_am_tx_control_pdu_allocation)); - list_add_tail_eurecom (pdu_status, &rlcP->control); - } -} - -//----------------------------------------------------------------------------- -void -rlc_am_process_sdu_discarded (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - // We assume that the list sdu_discarded contains sdu(s) - /* From 3GPP TS 25.322 V4.3.0 (2001-12) - The Sender shall initiate the SDU discard with explicit signalling procedure if one of the - following triggers is detected: - - "Timer based SDU discard with explicit signalling" is configured, Timer_Discard expires - for an SDU, and one or more segments of the SDU have been submitted to a lower layer; - - "Timer based SDU discard with explicit signalling" is configured, Timer_Discard expires - for an SDU, and Send MRW is configured; - - "SDU discard after MaxDAT number of transmissions" is configured, and MaxDAT number of - transmissions is reached (i.e. VT(DAT) � MaxDAT) for an AMD PDU. - */ - // discard procedure - if ((rlcP->send_mrw & RLC_AM_SEND_MRW_ON)) { - rlc_am_sdu_discard_with_explicit_signalling_procedure_send_mrw_configured (rlcP); - - } else { // RLC_AM_SEND_MRW_OFF - rlc_am_sdu_discard_with_explicit_signalling_procedure_send_mrw_not_configured (rlcP); - } - - rlc_am_schedule_procedure (rlcP); -} - -//----------------------------------------------------------------------------- -void -rlc_am_sdu_discard_with_explicit_signalling_procedure_send_mrw_configured (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - /* From 3GPP TS 25.322 V5.0.0 (2002-03) - The Sender shall: - - if "Send MRW" is configured: - - if the last discarded SDU ended in an AMD PDU, and its "Length Indicator" is present in the same AMD - PDU, and no new SDU is present inside this AMD PDU: - - set the last SN_MRWi field in the MRW SUFI to 1 + "Sequence Number" of the AMD PDU which - contains the "Length Indicator" of the last discarded SDU; - - set the NLENGTH field in the MRW SUFI to "0000". - - otherwise: - - set the last SN_MRWi field in the MRW SUFI to the "Sequence Number" of the AMD PDU which - contains the "Length Indicator" of the last discarded SDU; - - set the NLENGTH field in the MRW SUFI so that the last data octet to be discarded in the Receiver shall be - the octet indicated by the NLENGTH:th "Length Indicator" field of the AMD PDU which contains the - "Length Indicator" of the last discarded SDU; - - set each of the other SN_MRWi fields in the MRW SUFI to the "Sequence Number" of the AMD PDU which - contains the "Length Indicator" of the i:th discarded SDU. - - if the MRW SUFI contains only one SN_MRWi field and the value of SN_MRWi field - VT(A)+Configured_Tx_Window_Size: - - set the LENGTH field in the MRW SUFI to "0000". - - otherwise: - - set the LENGTH field in the MRW SUFI to the number of SN_MRWi fields in the same MRW SUFI. In this - case, SN_MRW1 shall be in the interval VT(A) SN_MRW1 < VT(A)+Configured_Tx_Window_Size. - */ - mem_block_t* mb_discard_procedure = NULL; - mem_block_t* sdu_discarded; - struct rlc_am_tx_sdu_management* last_sdu_discarded_mngt; - mem_block_t* le; - struct rlc_am_status_header* pdu; - uint8_t* p8; - int last_sn_mrw_length; - uint8_t count_sdu_discarded; - uint8_t byte_aligned; -#ifdef DEBUG_RLC_AM_DISCARD - uint16_t sn_mrw_length; -#endif - - while (rlcP->sdu_discarded.head) { - // alloc a discard procedure - mb_discard_procedure = get_free_mem_block (sizeof (struct rlc_am_discard_procedure)); - memset (mb_discard_procedure->data, 0, sizeof (struct rlc_am_discard_procedure)); - list_init (&((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->sdu_list, NULL); - count_sdu_discarded = 0; - // assign sdu discarded to discard procedure - // sdu headers are registered in discard procedure - last_sn_mrw_length = -1; - - while ((rlcP->sdu_discarded.head) && (count_sdu_discarded < 15)) { // max 15 sdu discarded per procedure - sdu_discarded = list2_remove_head (&rlcP->sdu_discarded); - - // this test is done to avoid signalling n times the same SN_MRW_length if a pdu contains n sdu - // so it can save some discard procedures. - if (last_sn_mrw_length != ((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn) { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD IN PROCEDURE %p ADD SDU SN_MRWlength 0x%03X\n", rlcP->rb_id, mb_discard_procedure, - ((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn); -#endif - list_add_tail_eurecom (sdu_discarded, &((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->sdu_list); - last_sn_mrw_length = ((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn; - count_sdu_discarded += 1; - - } else { - free_mem_block (sdu_discarded); - } - } - - ((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->length = count_sdu_discarded; - //((struct rlc_am_discard_procedure*)(mb_discard_procedure->data))->nlength = ((struct rlc_am_sdu_discard_management*)((mem_block_t*)(sdu_header_copy_copy->data))->data)->li_index_for_discard; - last_sdu_discarded_mngt = (struct rlc_am_tx_sdu_management*) (sdu_discarded->data); - - if ((last_sdu_discarded_mngt->no_new_sdu_segmented_in_last_pdu)) { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD NO NEW SDU SEGMENTED IN LAST PDU DISCARDED\n", rlcP->rb_id); -#endif - last_sdu_discarded_mngt->last_pdu_sn = (last_sdu_discarded_mngt->last_pdu_sn + 1) & SN_12BITS_MASK; - ((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->nlength = 0; - - } else { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD OTHER SDU(s) SEGMENTED IN LAST PDU DISCARDED\n", rlcP->rb_id); -#endif - ((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->nlength = last_sdu_discarded_mngt->li_index_for_discard + - 1; // +1 since numerotation begins at 1 - } - -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD SET SN_MRW_LENGTH 0x%04X NLENGTH = %d \n", rlcP->rb_id, last_sdu_discarded_mngt->last_pdu_sn, - ((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->nlength); - sn_mrw_length = last_sdu_discarded_mngt->last_pdu_sn; -#endif - // make status pdu - le = get_free_mem_block (rlcP->pdu_size + sizeof (struct rlc_am_tx_control_pdu_allocation) + GUARD_CRC_LIH_SIZE); - - if (le == NULL) { - // be carefull : lost resources in mb_discard : TO DO - msg ("[RLC_AM][RB %d] FATAL ERROR : OUT OF MEMORY\n", rlcP->rb_id); - return; - - } else { - ((struct rlc_am_tx_control_pdu_management*) (le->data))->rlc_tb_type = RLC_AM_MRW_STATUS_PDU_TYPE; - pdu = (struct rlc_am_status_header*) (&le->data[sizeof (struct rlc_am_tx_control_pdu_allocation)]); - pdu->byte1 = RLC_PDU_TYPE_STATUS; - p8 = &(pdu->byte1); - *p8 = *p8 | RLC_AM_SUFI_MRW; - p8 = p8 + 1; - // fill field LENGTH - *p8 = (count_sdu_discarded << 4); - byte_aligned = 0; - // fill fields SN_MRWi - sdu_discarded = (((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->sdu_list.head); // reuse of var sdu_discarded - - while ((count_sdu_discarded)) { - count_sdu_discarded -= 1; - - if (byte_aligned) { - *p8 = ((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn >> 4; - p8 = p8 + 1; - *p8 = ((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn << 4; - byte_aligned = 0; - - } else { - //*p8 = 0 << 4 | (temp_sn >> 8); - *p8 |= (((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn >> 8); - p8 = p8 + 1; - *p8 = ((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn; - p8 = p8 + 1; - byte_aligned = 1; - } - - sdu_discarded = sdu_discarded->next; - } - - // fill field Nlength - if (byte_aligned) { - *p8 = (((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->nlength << 4) | RLC_AM_SUFI_NO_MORE; - - } else { - *p8 |= (((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->nlength); - p8 = p8 + 1; - *p8 = (RLC_AM_SUFI_NO_MORE << 4); - } - - ((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->control_pdu = le; - list2_add_tail (mb_discard_procedure, &rlcP->discard_procedures); - } - } - -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD QUEUED NEW PROCEDURE SEND_MRW IS CONFIGURED SN_MRW_length = 0x%04X length %d nlength %d\n", - rlcP->rb_id, sn_mrw_length, ((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->length, - ((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->nlength); -#endif -} - -//----------------------------------------------------------------------------- -void -rlc_am_sdu_discard_with_explicit_signalling_procedure_send_mrw_not_configured (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - /* From 3GPP TS 25.322 V5.0.0 (2002-03) - The Sender shall: - - if "Send MRW" is NOT configured: - - if the last SDU to be discarded in the Receiver ended in an AMD PDU, and its "Length Indicator" is present - in the same AMD PDU, and no new SDU is present inside this AMD PDU: - - set the last SN_MRWi field in the MRW SUFI to 1 + "Sequence Number" of the AMD PDU which - contains the "Length Indicator" of the last SDU to be discarded in the Receiver; - - set the NLENGTH field in the MRW SUFI to "0000". - - otherwise: - - set the last SN_MRWi field in the MRW SUFI to the "Sequence Number" of the AMD PDU which - contains the "Length Indicator" of the last SDU to be discarded in the Receiver; - - set the NLENGTH field in the MRW SUFI so that the last data octet to be discarded in the Receiver shall be - the octet indicated by the NLENGTH:th "Length Indicator" field of the AMD PDU which contains the - "Length Indicator" of the last SDU to be discarded in the Receiver; - - optionally set each of the other SN_MRWi fields in the MRW SUFI to the "Sequence Number" of the AMD - PDU which contains the "Length Indicator" of the i:th SDU to be discarded in the Receiver; - - if the MRW SUFI contains only one SN_MRWi field and the value of SN_MRWi field - VT(A)+Configured_Tx_Window_Size: - - set the LENGTH field in the MRW SUFI to "0000". - - otherwise: - - set the LENGTH field in the MRW SUFI to the number of SN_MRWi fields in the same MRW SUFI. In this - case, SN_MRW1 shall be in the interval VT(A) SN_MRW1 < VT(A)+Configured_Tx_Window_Size. - */ - mem_block_t* mb_discard_procedure = NULL; - mem_block_t* sdu_discarded; - struct rlc_am_tx_sdu_management* last_sdu_discarded_mngt; - mem_block_t* le; - struct rlc_am_status_header* pdu; - int last_sn_mrw_length; - uint8_t* p8; - uint8_t count_sdu_discarded; - uint8_t byte_aligned; -#ifdef DEBUG_RLC_AM_DISCARD - uint16_t sn_mrw_length; -#endif - - while (rlcP->sdu_discarded.head) { - // alloc a discard procedure - mb_discard_procedure = get_free_mem_block (sizeof (struct rlc_am_discard_procedure)); - memset (mb_discard_procedure->data, 0, sizeof (struct rlc_am_discard_procedure)); - list_init (&((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->sdu_list, NULL); - count_sdu_discarded = 0; - // assign sdu discarded to discard procedure - // sdu headers are registered in discard procedure - last_sn_mrw_length = -1; - - while ((rlcP->sdu_discarded.head) && (count_sdu_discarded < 15)) { // max 15 sdu discarded per procedure - sdu_discarded = list2_remove_head (&rlcP->sdu_discarded); - - // this test is done to avoid signalling n times the same SN_MRW_length if a pdu contains n sdu - // so it can save some discard procedures. - if (last_sn_mrw_length != ((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn) { -#ifdef DEBUG_RLC_AM_DISCARD - msg ("[RLC_AM][RB %d] DISCARD IN PROCEDURE %p ADD SDU SN_MRWlength %03X hex\n", rlcP->rb_id, mb_discard_procedure, - ((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn); -#endif - list_add_tail_eurecom (sdu_discarded, &((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->sdu_list); - last_sn_mrw_length = ((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn; - count_sdu_discarded = 1; - - } else { - free_mem_block (sdu_discarded); - } - } - - ((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->length = count_sdu_discarded; - //((struct rlc_am_discard_procedure*)(mb_discard_procedure->data))->nlength = ((struct rlc_am_sdu_discard_management*)((mem_block_t*)(sdu_header_copy_copy->data))->data)->li_index_for_discard; - last_sdu_discarded_mngt = (struct rlc_am_tx_sdu_management*) (sdu_discarded->data); - - if ((last_sdu_discarded_mngt->no_new_sdu_segmented_in_last_pdu)) { - last_sdu_discarded_mngt->last_pdu_sn = (last_sdu_discarded_mngt->last_pdu_sn + 1) & SN_12BITS_MASK; - ((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->nlength = 0; - - } else { - ((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->nlength = last_sdu_discarded_mngt->li_index_for_discard; - } - -#ifdef DEBUG_RLC_AM_DISCARD - sn_mrw_length = last_sdu_discarded_mngt->last_pdu_sn; -#endif - - // make status pdu - if ((le = get_free_mem_block (rlcP->pdu_size + sizeof (struct rlc_am_tx_control_pdu_allocation) + GUARD_CRC_LIH_SIZE))) { - ((struct rlc_am_tx_control_pdu_management*) (le->data))->rlc_tb_type = RLC_AM_MRW_STATUS_PDU_TYPE; - pdu = (struct rlc_am_status_header*) (&le->data[sizeof (struct rlc_am_tx_control_pdu_allocation)]); - pdu->byte1 = RLC_PDU_TYPE_STATUS; - p8 = &(pdu->byte1); - *p8 = *p8 | RLC_AM_SUFI_MRW; - p8 = p8 + 1; - // fill field LENGTH - *p8 = (count_sdu_discarded << 4); - byte_aligned = 0; - // fill fields SN_MRWi - sdu_discarded = (((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->sdu_list.head); // reuse of var sdu_discarded - //*p8 = 0 << 4 | (temp_sn >> 8); - *p8 |= (((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn >> 8); - p8 = p8 + 1; - *p8 = ((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn; - p8 = p8 + 1; - byte_aligned = 1; - // fill field Nlength - *p8 = (((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->nlength << 4) | RLC_AM_SUFI_NO_MORE; - ((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->control_pdu = le; - list2_add_tail (mb_discard_procedure, &rlcP->discard_procedures); - - } else { - // out of memory - return; - } - } -} diff --git a/openair2/LAYER2/RLC/AM/rlc_am_discard_tx_proto_extern.h b/openair2/LAYER2/RLC/AM/rlc_am_discard_tx_proto_extern.h deleted file mode 100755 index abc3878b085084e81b61ab595270b2ee90243e61..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_discard_tx_proto_extern.h +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_discard_tx_proto_extern.h - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - ***************************************************************************/ -# ifndef __RLC_AM_DISCARD_TX_PROTO_EXTERN_H__ -# define __RLC_AM_DISCARD_TX_PROTO_EXTERN_H__ -//----------------------------------------------------------------------------- -# include "rlc_am_entity.h" -# include "rlc_am_structs.h" -# include "mem_block.h" -//----------------------------------------------------------------------------- -extern void rlc_am_schedule_procedure (struct rlc_am_entity *rlcP); -extern void rlc_am_process_sdu_discarded (struct rlc_am_entity *rlcP); -extern void rlc_am_sdu_discard_with_explicit_signalling_procedure_send_mrw_configured (struct rlc_am_entity *rlcP); -extern void rlc_am_sdu_discard_with_explicit_signalling_procedure_send_mrw_not_configured (struct rlc_am_entity *rlcP); -# endif diff --git a/openair2/LAYER2/RLC/AM/rlc_am_entity.h b/openair2/LAYER2/RLC/AM/rlc_am_entity.h deleted file mode 100755 index 30426bc83fe857fba92e3405b1be73194cd6beb1..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_entity.h +++ /dev/null @@ -1,326 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_entity.h - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - ***************************************************************************/ -# ifndef __RLC_AM_ENTITY_H__ -# define __RLC_AM_ENTITY_H__ -//----------------------------------------------------------------------------- -# include "mem_block.h" -# include "rlc_am_structs.h" -# include "rlc_def.h" -# include "platform_types.h" -# include "platform_constants.h" -//----------------------------------------------------------------------------- -struct rlc_am_entity { - module_id_t module_id; - // for stats and trace purpose : - uint16_t data_plane; // act as a boolean - - uint16_t rb_id; - //----------------------------- - // polling info - //----------------------------- - uint16_t poll_pdu_trigger; - uint16_t poll_sdu_trigger; - uint16_t timer_poll_trigger; - uint16_t timer_poll_prohibit_trigger; - uint8_t last_transmission_pdu_poll_trigger; - uint8_t last_retransmission_pdu_poll_trigger; - uint8_t poll_window_trigger; - //----------------------------- - // timers - //----------------------------- - list2_t rlc_am_timer_list; - //uint16_t timer_poll; - //uint16_t timer_poll_prohibit; - - uint16_t timer_poll_periodic; - //uint16_t timer_status_prohibit; - uint16_t timer_status_periodic; - - signed int timer_status_prohibit; - signed int running_timer_status_prohibit; - - - mem_block_t *timer_rst; - uint16_t time_out_events; - mem_block_t *timer_mrw; // if NULL : no timer is running - //uint8_t timer_mrw_is_running; - - uint8_t max_mrw; - //uint16_t timer_poll_init; - //uint16_t timer_poll_prohibit_init; - //uint16_t timer_epc_init; - uint16_t timer_discard_init; - uint16_t timer_poll_periodic_init; - //uint16_t timer_status_prohibit_init; - //uint16_t timer_status_periodic_init; - uint16_t timer_rst_init; - uint16_t timer_mrw_init; - - uint32_t transmitted_pdu_types; - int last_tx_status_frame; - - uint32_t *frame_tick_milliseconds; // pointer on this tick variable handled by RRC : READ ONLY - - uint8_t missing_pdu_indicator; - //----------------------------- - // tranmission - //----------------------------- - - //struct cnt_dbl_lk_list_up segmentation_buffer; // output of segmentation/concatenation function - list2_t sdu_conf_segmented; // contain sdu_headers:sdu processed by the segmentation unit. (we keep them for confirm) - list2_t sdu_discard_segmented; // contain sdu_headers:sdu processed by the segmentation unit. (we keep them for discard) - list2_t sdu_discarded; // contain sdu_headers - - list2_t discard_procedures; // contain procedures (struct rlc_am_discard_procedure) - - //struct cnt_dbl_lk_list_up transmission_buffer; // output of mux module - - //uint16_t data_pdu_size; - //uint16_t control_pdu_size; - - - - //struct cnt_list_up dcch_pdus_to_mac_layer; - //struct cnt_list_up dtch_pdus_to_mac_layer; - - //struct list_up dcch_pdus_from_mac_layer; - //struct list_up dtch_pdus_from_mac_layer; - - // implementation specific: our transmiter buffer is an array whose size must be a power of 2 -# define RLC_AM_DISCARD_REASSEMBLY_AT_LI_INDEX_0 0x00 - uint8_t discard_reassembly_after_li; // when received mrw sufi - uint16_t discard_reassembly_start_sn; - //----------------------------- - // management of received PDU for piggybacked status PDU and status PDU - //----------------------------- - struct sufi_to_insert_in_status status_in_construction[NB_MAX_SUFI]; - struct sufi_ack ack; - uint8_t sufi_to_insert_index; - //----------------------------- - // Reset - //----------------------------- - uint8_t send_status_pdu_requested; - uint8_t reset_sequence_number; - uint8_t last_received_rsn; - uint8_t max_rst; - //----------------------------- - // Mapping info - //----------------------------- - uint8_t dcch_logical_channel_identity; - uint8_t dtch_logical_channel_identity; - uint8_t nb_logical_channels_per_rlc; - //----------------------------- - // buffer occupancy measurements sent to MAC - //----------------------------- - // note occupancy of other buffers is deducted from nb elements in lists - uint32_t buffer_occupancy_retransmission_buffer; // nb of pdus - - //************************************************************** - // new members - //************************************************************** - uint8_t allocation; - uint8_t location; // UTRAN/UE - uint8_t protocol_state; - //----------------------------- - // protocol variables - //----------------------------- - uint16_t first_li_in_next_pdu; // indicates : - // value = 000000000000000 that the previous PDU was exactly - // with the last segment of an RLC SDU and there is no LI that - // indicates the end of the SDU in the previous RLC PDU. - // value = 111111111111011 The last segment of an RLC SDU was one octet - // short of exactly filling the previous RLC PDU and there is no LI that - // indicates the end of the SDU in the previous RLC PDU. The remaining one - // octet in the previous RLC PDU is ignored. - // value = 111111111111110 AMD PDU: The rest of the RLC PDU includes a - // piggybacked STATUS PDU. - // value = 111111111111111 The rest of the RLC PDU is padding. The padding - // length can be zero. - - uint16_t vt_s; // send state variable - // The sequence number of the next PDU to be transmitted for the - // first time(i.e. excluding retransmission). It is updated after - // transmission of a PDU, which includes not earlier transmitted - // PDUs and after transmission of a MRW SUFI which includes SN_MRW - // length > VT(S). - uint16_t vt_a; // Acknowledged state variable - // The sequence number of the next in sequence PDU expected to be - // acknowledged, which forms the lower edge of the window of acceptable - // acknowledgments. VT(A) is updated based on a receipt of a STATUS - // PDU including an ACK and/or MRW_ACK super field. - uint16_t max_dat; // This state variable counts the number of times a PDU has been transmited - // There is one vt(dat) for each PDU and it is incremented each time the pdu - // is transmited. The initial value of this variable is 0; - uint16_t vt_ms; // Maximun send state variable - // The sequence number of the first PDU not allowed by the receiver - // [the receiver will allow up to VT(MS)-1], VT(MS) = VT(A)+VT(WS). - // This value represents the upper edge of the transmit window. The - // transmitter shall not transmit a PDU with SN>=VT(MS). VT(MS) is - // updated when either VT(A) or VT(WS) is updated. The PDU with SN - // VT(S)-1 can be transmitted also when VT(S) >= VT(MS). - uint16_t vt_pdu; // not used - uint16_t vt_sdu; // this state variable is used when the poll every Poll_SDU SDU - // function is used. It is incremented with 1 each SDU is - // transmitted. When it reaches Poll_SDU a new poll is transmitted - // the state variable is set to 0. The poll bit should be set in the - // PDU that contains the last segment of the SDU. - uint16_t vt_rst; // Reset state variable - // it is used to count the number of times a RESET PDU is transmitted. - // vt(rst) is incremented with 1 each time a RESET PDU is transmitted. VT(rst) is - // reset only upon the reception of a RESET ACK PDU, i.e. VT(RST) is not reset when - // an RLC RESET occurs which was initiated from the peer RLC entity. The initial value - // of this variable is 0. - uint16_t vt_mrw; // MRW command send state variable - // It is used to count the number of times a MRW command is transmitted. - // VT(MRW) is reset when the discard procedure is terminated. - uint16_t vt_ws; // transmitter window size state variable - // The size that should be used for the transmitter window. VT(WS) - //is set equal to the WSN field when the transmitter receives a - // STATUS PDU including a WindowSize super-field. - uint16_t vr_r; // Receive state variable - // The sequence number of the next in sequence PDU expected to be - // received. It is equal to SNmax+1 upon receipt of the next in - // sequence PDU, where SNmax is the sequence number of the highest - // received in sequence PDU. The initial value of this variable is 0 - uint16_t vr_h; // Highest expected state variable - // The sequence number of the highest expected PDU. this state - // variable is set equal to SN+1 only when a new PDU is received - // with VR(MR)>SN>=VR(H). The initial value of this variable is 0. - uint16_t vr_mr; // Maximum acceptable Receive state variable - // The sequence number of the first PDU not allowed by the receiver. - // It shall be set equal to SN+1 upon reception of a PDU. The - // initial value of this variable is 0. - int16_t vr_ep; // Estimated PDU counter state variable - // The number of PDUs that should be received yet as a consequence - // of the transmission of the latest status report. In acknowledged - // mode, this state variable is updated at the end of each TTI. It - // is decremented by the number of PDUs that should have been - // received during the TTI. If VR(EP) is equal to 0, then check if - // all PDUs requested for retransmission in the latest status report - // have been received. - - //----------------------------- - // C-SAP - //----------------------------- - list_t c_sap; - - //----------------------------- - // discard - //----------------------------- - uint8_t sdu_discard_mode; - uint8_t send_mrw; - //----------------------------- - // tranmission - //----------------------------- - mem_block_t **input_sdus; // should be accessed as an array - mem_block_t *input_sdus_alloc; // allocation of the array - uint16_t size_input_sdus_buffer; - uint16_t nb_sdu; - - uint16_t next_sdu_index; // next location of incoming sdu - uint16_t current_sdu_index; - uint32_t buffer_occupancy; - // for segmentation procedures (optimization save space on stack) - uint16_t li[RLC_AM_SEGMENT_NB_MAX_LI_PER_PDU]; - - - uint16_t configured_tx_window_size; - // implementation specific: our transmiter buffer is an array whose size must be a power of 2 - uint16_t recomputed_configured_tx_window_size; - - mem_block_t *(*rlc_segment) (struct rlc_am_entity * rlcP); - - mem_block_t *retransmission_buffer_alloc; - mem_block_t **retransmission_buffer; - - list2_t retransmission_buffer_to_send; // contains PDUs that must be immediatly retransmitted - list_t control; // contains control pdus - - uint16_t nb_pdu_requested_by_mac_on_ch1; - uint16_t nb_pdu_requested_by_mac_on_ch2; - uint16_t pdu_size; - - uint8_t li_one_byte_short_to_add_in_next_pdu; - uint8_t li_exactly_filled_to_add_in_next_pdu; - - list_t pdus_to_mac_layer_ch1; - list_t pdus_to_mac_layer_ch2; - - //----------------------------- - // receiver - //----------------------------- - sdu_size_t output_sdu_size_to_write; - mem_block_t *output_sdu_in_construction; - - mem_block_t *receiver_buffer_alloc; - mem_block_t **receiver_buffer; - - uint16_t last_reassemblied_sn; - uint16_t configured_rx_window_size; - uint16_t recomputed_configured_rx_window_size; - - list_t pdus_from_mac_layer_ch1; - list_t pdus_from_mac_layer_ch2; - - //----------------------------- - // status generation - //----------------------------- - mem_block_t *holes_alloc; - struct rlc_am_hole *holes; - uint16_t nb_missing_pdus; - uint16_t ack_sn; - uint16_t nb_holes; -# ifdef BYPASS_L1 - unsigned int pdu_counter; -# endif - - - unsigned int stat_tx_pdcp_sdu; - unsigned int stat_tx_pdcp_sdu_discarded; - unsigned int stat_tx_retransmit_pdu_unblock; - unsigned int stat_tx_retransmit_pdu_by_status; - unsigned int stat_tx_retransmit_pdu; - unsigned int stat_tx_data_pdu; - unsigned int stat_tx_control_pdu; - - unsigned int stat_rx_sdu; - unsigned int stat_rx_error_pdu; - unsigned int stat_rx_data_pdu; - unsigned int stat_rx_data_pdu_out_of_window; - unsigned int stat_rx_control_pdu; -}; -# endif diff --git a/openair2/LAYER2/RLC/AM/rlc_am_errno.h b/openair2/LAYER2/RLC/AM/rlc_am_errno.h deleted file mode 100755 index 6ea278fa3a0eae26e7338dcba502479595a421f7..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_errno.h +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -# ifndef __RLC_AM_ERRNO_H__ -# define __RLC_AM_ERRNO_H__ -# endif - -# define RLC_AM_OUT_OF_MEMORY_ERROR 1 -# define RLC_AM_VT_S_OVERFLOW_ERROR 2 -# define RLC_AM_RETRANS_REQ_PDU_NULL 3 -# define RLC_AM_RETRANS_REQ_PDU_DONE_BEFORE 4 diff --git a/openair2/LAYER2/RLC/AM/rlc_am_fsm.c b/openair2/LAYER2/RLC/AM/rlc_am_fsm.c deleted file mode 100755 index ea1e9d489c4d4ff7044b82c6651cebe927ff4bbe..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_fsm.c +++ /dev/null @@ -1,236 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_fsm.c - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - ***************************************************************************/ -#include "rtos_header.h" -#include "platform_types.h" -//----------------------------------------------------------------------------- -#include "rlc_am_entity.h" -#include "rlc_am_constants.h" -#include "rlc_def.h" -#include "LAYER2/MAC/extern.h" -//----------------------------------------------------------------------------- -int -rlc_am_fsm_notify_event (struct rlc_am_entity* rlcP, uint8_t eventP) -{ - //----------------------------------------------------------------------------- - switch (rlcP->protocol_state) { - //------------------------------- - // RLC_NULL_STATE - //------------------------------- - case RLC_NULL_STATE: - switch (eventP) { - case RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_DATA_TRANSFER_READY_STATE_EVENT: -#ifdef DEBUG_RLC_AM_FSM - msg ("[RLC_AM][RB %d][FSM] RLC_NULL_STATE -> RLC_DATA_TRANSFER_READY_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame); -#endif - rlcP->protocol_state = RLC_DATA_TRANSFER_READY_STATE; - return 1; - break; - - default: - msg ("[RLC_AM][RB %d][FSM] WARNING PROTOCOL ERROR - EVENT %02X hex NOT EXPECTED FROM NULL_STATE frame %d\n", rlcP->rb_id, eventP, Mac_rlc_xface->frame); - return 0; - } - - break; - - //------------------------------- - // RLC_DATA_TRANSFER_READY_STATE - //------------------------------- - case RLC_DATA_TRANSFER_READY_STATE: - switch (eventP) { - case RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_NULL_STATE_EVENT: -#ifdef DEBUG_RLC_AM_FSM - msg ("[RLC_AM][RB %d][FSM] RLC_DATA_TRANSFER_READY_STATE -> RLC_NULL_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame); -#endif - rlcP->protocol_state = RLC_NULL_STATE; - return 1; - break; - - case RLC_AM_RECEIVE_RESET_EVENT: - case RLC_AM_TRANSMIT_RESET_ACK_EVENT: - return 1; - break; - - case RLC_AM_TRANSMIT_RESET_EVENT: -#ifdef DEBUG_RLC_AM_FSM - msg ("[RLC_AM][RB %d][FSM] RLC_DATA_TRANSFER_READY_STATE -> RLC_RESET_PENDING_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame); -#endif - rlcP->protocol_state = RLC_RESET_PENDING_STATE; - return 1; - break; - - case RLC_AM_RECEIVE_CRLC_SUSPEND_REQ_EVENT: - case RLC_AM_TRANSMIT_CRLC_SUSPEND_CNF_EVENT: -#ifdef DEBUG_RLC_AM_FSM - msg ("[RLC_AM][RB %d][FSM] RLC_DATA_TRANSFER_READY_STATE -> RLC_LOCAL_SUSPEND_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame); -#endif - rlcP->protocol_state = RLC_LOCAL_SUSPEND_STATE; - return 1; - break; - - default: - msg ("[RLC_AM][RB %d][FSM] WARNING PROTOCOL ERROR - EVENT 0x%02X NOT EXPECTED FROM DATA_TRANSFER_READY_STATE frame %d\n", rlcP->rb_id, eventP, - Mac_rlc_xface->frame); - return 0; - } - - break; - - //------------------------------- - // RLC_RESET_PENDING_STATE - //------------------------------- - case RLC_RESET_PENDING_STATE: - switch (eventP) { - case RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_NULL_STATE_EVENT: -#ifdef DEBUG_RLC_AM_FSM - msg ("[RLC_AM][RB %d][FSM] RLC_RESET_PENDING_STATE -> RLC_NULL_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame); -#endif - rlcP->protocol_state = RLC_NULL_STATE; - return 1; - break; - - case RLC_AM_RECEIVE_RESET_EVENT: - case RLC_AM_TRANSMIT_RESET_ACK_EVENT: - case RLC_AM_TRANSMIT_RESET_EVENT: // WARNING: THIS EVENT IS NOT IN SPECS BUT MAY BE AN OMISSION ???? - return 1; - break; - - case RLC_AM_RECEIVE_RESET_ACK_EVENT: -#ifdef DEBUG_RLC_AM_FSM - msg ("[RLC_AM][RB %d][FSM] RLC_RESET_PENDING_STATE -> RLC_DATA_TRANSFER_READY_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame); -#endif - rlcP->protocol_state = RLC_DATA_TRANSFER_READY_STATE; - return 1; - break; - - case RLC_AM_RECEIVE_CRLC_SUSPEND_REQ_EVENT: - case RLC_AM_TRANSMIT_CRLC_SUSPEND_CNF_EVENT: -#ifdef DEBUG_RLC_AM_FSM - msg ("[RLC_AM][RB %d][FSM] RLC_RESET_PENDING_STATE -> RLC_RESET_AND_SUSPEND_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame); -#endif - rlcP->protocol_state = RLC_RESET_AND_SUSPEND_STATE; - return 1; - break; - - default: - msg ("[RLC_AM][RB %d][FSM] WARNING PROTOCOL ERROR - EVENT 0x%02X NOT EXPECTED FROM RLC_RESET_PENDING_STATE frame %d\n", rlcP->rb_id, eventP, - Mac_rlc_xface->frame); - return 0; - } - - break; - - //------------------------------- - // RLC_RESET_AND_SUSPEND_STATE - //------------------------------- - case RLC_RESET_AND_SUSPEND_STATE: - switch (eventP) { - case RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_NULL_STATE_EVENT: -#ifdef DEBUG_RLC_AM_FSM - msg ("[RLC_AM][RB %d][FSM] RLC_RESET_AND_SUSPEND_STATE -> RLC_NULL_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame); -#endif - rlcP->protocol_state = RLC_NULL_STATE; - return 1; - break; - - case RLC_AM_RECEIVE_RESET_ACK_EVENT: -#ifdef DEBUG_RLC_AM_FSM - msg ("[RLC_AM][RB %d][FSM] RLC_RESET_AND_SUSPEND_STATE -> RLC_LOCAL_SUSPEND_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame); -#endif - rlcP->protocol_state = RLC_LOCAL_SUSPEND_STATE; - return 1; - break; - - case RLC_AM_RECEIVE_CRLC_RESUME_REQ_EVENT: -#ifdef DEBUG_RLC_AM_FSM - msg ("[RLC_AM][RB %d][FSM] RLC_RESET_AND_SUSPEND_STATE -> RLC_RESET_PENDING_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame); -#endif - rlcP->protocol_state = RLC_RESET_PENDING_STATE; - return 1; - break; - - default: - msg ("[RLC_AM][RB %d][FSM] WARNING PROTOCOL ERROR - EVENT 0x%02X NOT EXPECTED FROM RLC_RESET_AND_SUSPEND_STATE frame %d\n", rlcP->rb_id, eventP, - Mac_rlc_xface->frame); - return 0; - } - - break; - - //------------------------------- - // RLC_LOCAL_SUSPEND_STATE - //------------------------------- - case RLC_LOCAL_SUSPEND_STATE: - switch (eventP) { - case RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_NULL_STATE_EVENT: -#ifdef DEBUG_RLC_AM_FSM - msg ("[RLC_AM][RB %d][FSM] RLC_LOCAL_SUSPEND_STATE -> RLC_NULL_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame); -#endif - rlcP->protocol_state = RLC_NULL_STATE; - return 1; - break; - - case RLC_AM_RECEIVE_CRLC_RESUME_REQ_EVENT: -#ifdef DEBUG_RLC_AM_FSM - msg ("[RLC_AM][RB %d][FSM] RLC_LOCAL_SUSPEND_STATE -> RLC_DATA_TRANSFER_READY_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame); -#endif - rlcP->protocol_state = RLC_DATA_TRANSFER_READY_STATE; - return 1; - break; - - case RLC_AM_TRANSMIT_RESET_EVENT: -#ifdef DEBUG_RLC_AM_FSM - msg ("[RLC_AM][RB %d][FSM] RLC_LOCAL_SUSPEND_STATE -> RLC_RESET_AND_SUSPEND_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame); -#endif - rlcP->protocol_state = RLC_RESET_AND_SUSPEND_STATE; - return 1; - break; - - default: - msg ("[RLC_AM][RB %d][FSM] WARNING PROTOCOL ERROR - EVENT 0x%02X NOT EXPECTED FROM RLC_LOCAL_SUSPEND_STATE frame %d\n", rlcP->rb_id, eventP, - Mac_rlc_xface->frame); - return 0; - } - - break; - - default: - msg ("[RLC_AM][RB %d][FSM] ERROR UNKNOWN STATE %d\n", rlcP->rb_id, rlcP->protocol_state); - return 0; - } -} diff --git a/openair2/LAYER2/RLC/AM/rlc_am_fsm_proto_extern.h b/openair2/LAYER2/RLC/AM/rlc_am_fsm_proto_extern.h deleted file mode 100755 index 6739a3634d6045b9881890a5657df88d957b5393..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_fsm_proto_extern.h +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_fsm_proto_extern.h - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - ***************************************************************************/ -# ifndef __RLC_AM_FSM_PROTO_EXTERN_H__ -# define __RLC_AM_FSM_PROTO_EXTERN_H__ -//----------------------------------------------------------------------------- -# include "platform_types.h" -# include "rlc_am_entity.h" -//----------------------------------------------------------------------------- -extern int rlc_am_fsm_notify_event (struct rlc_am_entity *rlcP, uint8_t eventP); -# endif diff --git a/openair2/LAYER2/RLC/AM/rlc_am_mac_status.c b/openair2/LAYER2/RLC/AM/rlc_am_mac_status.c deleted file mode 100755 index 2a18ae020bc5d9dbb5200d9a0b2a326c5d051f10..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_mac_status.c +++ /dev/null @@ -1,103 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_mac_status.c - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - ***************************************************************************/ -#include "rtos_header.h" -#include "platform_types.h" -//----------------------------------------------------------------------------- -#include "rlc_am_entity.h" -#include "rlc_am_timers_proto_extern.h" -#include "rlc_am_discard_notif_proto_extern.h" -#include "rlc_am_reset_proto_extern.h" -#include "rlc_am_fsm_proto_extern.h" -#include "umts_timer_proto_extern.h" -//----------------------------------------------------------------------------- -void -rlc_am_status_report_from_mac (void* rlcP, uint16_t eventP) -{ - //----------------------------------------------------------------------------- - struct rlc_am_entity* rlc = (struct rlc_am_entity*) rlcP; - - //---------------------------------------- - // STATUS - //---------------------------------------- - if ((eventP & RLC_AM_FIRST_STATUS_PDU_TYPE) == RLC_AM_FIRST_STATUS_PDU_TYPE) { -#ifdef DEBUG_RLC_AM_MAC_STATUS - msg ("[RLC_AM %p][MAC_STATUS] EVENT RLC_AM_FIRST_STATUS_PDU_TYPE\n", rlcP); -#endif - return; - } - - //---------------------------------------- - // DISCARD - //---------------------------------------- - if ((eventP & RLC_AM_MRW_STATUS_PDU_TYPE)) { -#ifdef DEBUG_RLC_AM_MAC_STATUS - msg ("[RLC_AM %p][MAC_STATUS] EVENT RLC_AM_MRW_STATUS_PDU_TYPE\n", rlcP); -#endif - - // rearm the timer - if (!(rlc->timer_mrw) && (rlc->discard_procedures.head)) { - rlc->timer_mrw = umts_add_timer_list_up (&rlc->rlc_am_timer_list, rlc_am_discard_notify_mrw_ack_time_out, rlc, - rlc->discard_procedures.head, (uint32_t) rlc->timer_mrw_init, *rlc->frame_tick_milliseconds); - } - - return; - } - - //---------------------------------------- - // RESET - //---------------------------------------- - if ((eventP & RLC_AM_RESET_PDU_TYPE)) { -#ifdef DEBUG_RESET - msg ("[RLC_AM %p][MAC_STATUS] EVENT RLC_AM_RESET_PDU_TYPE SENT ARMING RESET TIMER %d frames frame %d\n", rlcP, (uint32_t) rlc->timer_rst_init, - *rlc->frame_tick_milliseconds); -#endif - rlc->timer_rst = umts_add_timer_list_up (&rlc->rlc_am_timer_list, rlc_am_reset_time_out, rlcP, NULL, (uint32_t) rlc->timer_rst_init, - *rlc->frame_tick_milliseconds); - return; - } - - //---------------------------------------- - // RESET ACK - //---------------------------------------- - if ((eventP & RLC_AM_RESET_ACK_PDU_TYPE)) { -#ifdef DEBUG_RLC_AM_MAC_STATUS - msg ("[RLC_AM %p][MAC_STATUS] EVENT RLC_AM_RESET_ACK_PDU_TYPE\n", rlcP); -#endif - rlc_am_fsm_notify_event (rlc, RLC_AM_TRANSMIT_RESET_ACK_EVENT); - return; - } -} diff --git a/openair2/LAYER2/RLC/AM/rlc_am_mac_status_proto_extern.h b/openair2/LAYER2/RLC/AM/rlc_am_mac_status_proto_extern.h deleted file mode 100755 index 0c7b3e099ad86c1429ad80d132f5468cdf3e400d..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_mac_status_proto_extern.h +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_mac_status_proto_extern.h - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - ***************************************************************************/ -# ifndef __RLC_AM_MAC_STATUS_PROTO_EXTERN_H__ -# define __RLC_AM_MAC_STATUS_PROTO_EXTERN_H__ -//----------------------------------------------------------------------------- -# include "platform_types.h" -//----------------------------------------------------------------------------- -extern void rlc_am_status_report_from_mac (void *rlcP, uint16_t eventP); -# endif diff --git a/openair2/LAYER2/RLC/AM/rlc_am_mux.c b/openair2/LAYER2/RLC/AM/rlc_am_mux.c deleted file mode 100755 index 249d0f42a7da10bfd21cc0aaf2b72db5f2cdbbb1..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_mux.c +++ /dev/null @@ -1,953 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_mux.c - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - ***************************************************************************/ -#include "rtos_header.h" -#include "platform_types.h" -//----------------------------------------------------------------------------- -#include "rlc_am_entity.h" -#include "rlc_am_constants.h" -#include "list.h" -#include "mem_block.h" -#include "rlc_am_retrans_proto_extern.h" -#include "rlc_am_mac_status_proto_extern.h" -#include "rlc_am_discard_tx_proto_extern.h" -#include "rlc_am_proto_extern.h" -#include "LAYER2/MAC/extern.h" -//#define DEBUG_MUX -//#define DEBUG_RLC_AM_POLL - -#ifdef NODE_MT -/* - * mux PDUs from segmentation buffer and PDUs from retransmission buffer - * onto transmission buffer - */ -//----------------------------------------------------------------------------- -void -rlc_am_mux_ue (struct rlc_am_entity* rlcP, unsigned int traffic_typeP) -{ - //----------------------------------------------------------------------------- - mem_block_t* pdu; - mem_block_t* sdu; - mem_block_t* copy_pdu; - struct rlc_am_pdu_header* rlc_header; - int pool_is_set; - int index; - int sdu_index; - unsigned int j, segmentation_returned_pdu; - unsigned int data_pdu_tx; // data pdu effectively transmitted - unsigned int tx_pdu; - int16_t nb_pdu_to_transmit_ch1; - int16_t nb_pdu_to_transmit_ch2; -# ifdef DEBUG_MUX - uint16_t id; -# endif - data_pdu_tx = 0; - nb_pdu_to_transmit_ch1 = rlcP->nb_pdu_requested_by_mac_on_ch1; - nb_pdu_to_transmit_ch2 = rlcP->nb_pdu_requested_by_mac_on_ch2; - - // discard - if ((rlcP->sdu_discarded.head) && (traffic_typeP & RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS)) { - rlc_am_process_sdu_discarded (rlcP); - } - - /****************************************** - * CONTROL PDU * - ******************************************/ - // from TS25.322 V4.2.0 p13 - // In case two logical channels are configured in the uplink, AMD PDUs are transmitted - // on the first logical channel, and control PDUs are transmitted on the second logical - // channel. - if (rlcP->nb_logical_channels_per_rlc == 1) { - while ((rlcP->control.head) && (nb_pdu_to_transmit_ch1)) { - pdu = list_remove_head (&rlcP->control); - - if ((traffic_typeP & RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS)) { - tx_pdu = 1; - - } else { - if (((struct rlc_am_tx_control_pdu_management*) (pdu->data))->rlc_tb_type & (RLC_AM_RESET_PDU_TYPE | RLC_AM_RESET_ACK_PDU_TYPE)) { - tx_pdu = 1; - - } else { - tx_pdu = 0; - } - } - - if ((tx_pdu)) { - nb_pdu_to_transmit_ch1--; - // for polling - rlcP->vt_pdu++; - ((struct mac_tb_req*) (pdu->data))->rlc_tb_type = ((struct rlc_am_tx_control_pdu_management*) (pdu->data))->rlc_tb_type; - ((struct mac_tb_req*) (pdu->data))->rlc = rlcP; - ((struct mac_tb_req*) (pdu->data))->rlc_callback = rlc_am_status_report_from_mac; - ((struct mac_tb_req*) (pdu->data))->data_ptr = &pdu->data[sizeof (struct rlc_am_tx_control_pdu_allocation)]; - ((struct mac_tb_req*) (pdu->data))->first_bit = 0; - ((struct mac_tb_req*) (pdu->data))->tb_size_in_bits = rlcP->pdu_size << 3; - list_add_tail_eurecom (pdu, &rlcP->pdus_to_mac_layer_ch1); -# ifdef DEBUG_MUX - msg ("[RLC_AM][RB %d][MUX] TX CONTROL PDU CH1 VT(A) 0x%03X VT(S) 0x%03X VT(MS) 0x%03X VR(R) 0x%03X VR(MR) 0x%03X\n", - rlcP->rb_id, rlcP->vt_a, rlcP->vt_s, rlcP->vt_ms, rlcP->vr_r, rlcP->vr_mr); -# endif - - } else { - free_mem_block (pdu); - } - } - - } else if (rlcP->nb_logical_channels_per_rlc == 2) { - while ((rlcP->control.head) && (nb_pdu_to_transmit_ch2)) { - pdu = list_remove_head (&rlcP->control); - - if ((traffic_typeP & RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS)) { - tx_pdu = 1; - - } else { - if (((struct rlc_am_tx_control_pdu_management*) (pdu->data))->rlc_tb_type & (RLC_AM_RESET_PDU_TYPE | RLC_AM_RESET_ACK_PDU_TYPE)) { - tx_pdu = 1; - - } else { - tx_pdu = 0; - } - } - - if ((tx_pdu)) { - nb_pdu_to_transmit_ch2--; - // for polling - rlcP->vt_pdu++; - ((struct mac_tb_req*) (pdu->data))->rlc_tb_type = ((struct rlc_am_tx_control_pdu_management*) (pdu->data))->rlc_tb_type; - ((struct mac_tb_req*) (pdu->data))->rlc = rlcP; - ((struct mac_tb_req*) (pdu->data))->rlc_callback = rlc_am_status_report_from_mac; - ((struct mac_tb_req*) (pdu->data))->data_ptr = &pdu->data[sizeof (struct rlc_am_tx_control_pdu_allocation)]; - ((struct mac_tb_req*) (pdu->data))->first_bit = 0; - ((struct mac_tb_req*) (pdu->data))->tb_size_in_bits = rlcP->pdu_size << 3; - list_add_tail_eurecom (pdu, &rlcP->pdus_to_mac_layer_ch2); -# ifdef DEBUG_MUX - msg ("[RLC_AM][RB %d][MUX] TX CONTROL PDU CH2 VT(A) 0x%03X VT(S) 0x%03X VT(MS) 0x%03X VR(R) 0x%03X VR(MR) 0x%03X \n", - rlcP->rb_id, rlcP->vt_a, rlcP->vt_s, rlcP->vt_ms, rlcP->vr_r, rlcP->vr_mr); -# endif - - } else { - free_mem_block (pdu); - } - } - } - - if (traffic_typeP & RLC_AM_TRAFFIC_ALLOWED_FOR_DATA) { - /****************************************** - * RETRANSMITED DATA PDU * - ******************************************/ - // priority is then made at retransmitted PDUs - while ((rlcP->retransmission_buffer_to_send.head) && (nb_pdu_to_transmit_ch1) && !(rlcP->protocol_state & RLC_RESET_PENDING_STATE)) { - // each retransmission may send RLC in RESET STATE if no discard is configured - copy_pdu = list2_remove_head (&rlcP->retransmission_buffer_to_send); - // unlink the pdu in retransmission buffer and its copy (mechanism avoiding multi-retransmission of the same - // pdu in the same queue) - pdu = ((struct rlc_am_tx_data_pdu_management*) (copy_pdu->data))->copy; -# ifdef DEBUG_MUX - rlc_am_display_data_pdu7(copy_pdu); -# endif - ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->copy = NULL; - ((struct mac_tb_req*) (copy_pdu->data))->rlc_tb_type = ((struct rlc_am_tx_data_pdu_management*) (copy_pdu->data))->rlc_tb_type; - ((struct mac_tb_req*) (copy_pdu->data))->rlc = rlcP; - ((struct mac_tb_req*) (copy_pdu->data))->rlc_callback = rlc_am_status_report_from_mac; - ((struct mac_tb_req*) (copy_pdu->data))->data_ptr = ©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]; - ((struct mac_tb_req*) (copy_pdu->data))->first_bit = 0; - ((struct mac_tb_req*) (copy_pdu->data))->tb_size_in_bits = rlcP->pdu_size << 3; - list_add_tail_eurecom (copy_pdu, &rlcP->pdus_to_mac_layer_ch1); - nb_pdu_to_transmit_ch1--; - data_pdu_tx++; - - // for polling - if (rlcP->poll_pdu_trigger) { - rlcP->vt_pdu++; - - if (rlcP->vt_pdu >= rlcP->poll_pdu_trigger) { - // set poll bit - ((struct rlc_am_pdu_header*) (©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2 |= RLC_AM_P_STATUS_REPORT_REQUESTED; - rlcP->vt_pdu = 0; - - } else { - // reset poll bit - ((struct rlc_am_pdu_header*) (©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2 = - (((struct rlc_am_pdu_header*) (©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2) & ~RLC_AM_P_STATUS_REPORT_REQUESTED; - } - } - -# ifdef DEBUG_MUX - id = (((uint16_t) (((struct rlc_am_pdu_header*) (©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte1 & RLC_AM_SN_1ST_PART_MASK)) << 5) | - ((((struct rlc_am_pdu_header*) (©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2 & RLC_AM_SN_2ND_PART_MASK) >> 3); - msg ("[RLC_AM][RB %d][MUX] RETRANSMIT DATA PDU %04X VT(A) 0x%03X VT(S) 0x%03X VT(MS) 0x%03X VR(R) 0x%03X VR(MR) 0x%03X\n", - rlcP->rb_id, id, rlcP->vt_a, rlcP->vt_s, rlcP->vt_ms, rlcP->vr_r, rlcP->vr_mr); -# endif - } - - /****************************************** - * DATA PDU * - ******************************************/ - if (!(rlcP->protocol_state & RLC_RESET_PENDING_STATE)) { - segmentation_returned_pdu = 1; - - while ((nb_pdu_to_transmit_ch1) && (rlcP->vt_s != rlcP->vt_ms) && (segmentation_returned_pdu) && !(rlcP->protocol_state & RLC_RESET_PENDING_STATE)) { - if ((pdu = rlcP->rlc_segment (rlcP))) { - rlc_header = (struct rlc_am_pdu_header*) (&pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]); - // check polling - pool_is_set = 0; - - if (rlcP->poll_pdu_trigger) { - rlcP->vt_pdu++; - - // test every poll_PDU trigger - if (rlcP->vt_pdu >= rlcP->poll_pdu_trigger) { - ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->rlc_tb_type = RLC_AM_DATA_POLL_PDU_TYPE; - rlc_header->byte2 |= RLC_AM_P_STATUS_REPORT_REQUESTED; - rlcP->vt_pdu = 0; - pool_is_set = 1; -# ifdef DEBUG_RLC_AM_POLL - msg ("[RLC_AM %p] POOL SET BY poll_pdu trigger\n", rlcP); -# endif - } - } - - // test every poll_SDU trigger - if ((rlcP->poll_sdu_trigger) && (((struct rlc_am_tx_data_pdu_management*) (pdu->data))->last_pdu_of_sdu)) { - if (rlcP->vt_sdu >= rlcP->poll_sdu_trigger) { - ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->rlc_tb_type = RLC_AM_DATA_POLL_PDU_TYPE; - rlc_header->byte2 |= RLC_AM_P_STATUS_REPORT_REQUESTED; - rlcP->vt_sdu = 0; - pool_is_set = 1; -# ifdef DEBUG_RLC_AM_POLL - msg ("[RLC_AM %p] POOL SET BY poll_sdu trigger\n", rlcP); -# endif - - } else { - rlcP->vt_sdu += ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->last_pdu_of_sdu; - } - } - - if (!pool_is_set) { - // test last pdu in transmission buffer trigger == last sdu in input buffer in this implementation of RLC AM - if ((rlcP->last_transmission_pdu_poll_trigger > 0) && (rlcP->nb_sdu == 0)) { - ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->rlc_tb_type = RLC_AM_DATA_POLL_PDU_TYPE; - rlc_header->byte2 |= RLC_AM_P_STATUS_REPORT_REQUESTED; - pool_is_set = 1; -# ifdef DEBUG_RLC_AM_POLL - msg ("[RLC_AM %p] POOL SET BY last pdu in tr buffer trigger\n", rlcP); -# endif - } - - if (!pool_is_set) { - // test last pdu in retransmission buffer trigger - if ((rlcP->retransmission_buffer_to_send.head) && (rlcP->retransmission_buffer_to_send.head == rlcP->retransmission_buffer_to_send.tail) - && (rlcP->last_retransmission_pdu_poll_trigger)) { - ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->rlc_tb_type = RLC_AM_DATA_POLL_PDU_TYPE; - rlc_header->byte2 |= RLC_AM_P_STATUS_REPORT_REQUESTED; - pool_is_set = 1; -# ifdef DEBUG_RLC_AM_POLL - msg ("[RLC_AM %p] POOL SET BY last pdu in retrans buffer trigger\n", rlcP); -# endif - } - - if (!pool_is_set) { - // test window based trigger - if (rlcP->poll_window_trigger) { - j = (unsigned int) (((rlcP->vt_s + 4096) - rlcP->vt_a) % 4096) * 100 / rlcP->vt_ws; - - if (j >= rlcP->poll_window_trigger) { - ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->rlc_tb_type = RLC_AM_DATA_POLL_PDU_TYPE; - rlc_header->byte2 |= RLC_AM_P_STATUS_REPORT_REQUESTED; - pool_is_set = 1; -# ifdef DEBUG_RLC_AM_POLL - msg ("[RLC_AM %p][POOL] POOL SET BY window based trigger j=%d\n", rlcP, j); -# endif - } - } - } - } - } - - rlc_header->byte1 |= (rlcP->vt_s >> 5); - rlc_header->byte2 |= ((uint8_t) rlcP->vt_s << 3); - ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->sn = rlcP->vt_s; - insert_into_retransmission_buffer (rlcP, rlcP->vt_s % rlcP->recomputed_configured_tx_window_size, pdu); - - // check if timer based discard configured - if ((rlcP->sdu_discard_mode & RLC_SDU_DISCARD_TIMER_BASED_EXPLICIT)) { - for (index = 0; index < ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->nb_sdu; index++) { - sdu_index = ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->sdu[index]; - sdu = rlcP->input_sdus[sdu_index]; - - // mark the sdu as invalid except if confirm requested - if (!((struct rlc_am_tx_sdu_management*) (sdu->data))->confirm) { - ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->sdu[index] = -1; // tag sdu as non valid - } - - ((struct rlc_am_tx_sdu_management*) (sdu->data))->nb_pdus_time += 1; - - if ((((struct rlc_am_tx_sdu_management*) (sdu->data))->nb_pdus_time == - ((struct rlc_am_tx_sdu_management*) (sdu->data))->nb_pdus) && - !(((struct rlc_am_tx_sdu_management*) (sdu->data))->confirm) && (((struct rlc_am_tx_sdu_management*) (sdu->data))->segmented) - ) { - ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->sdu[index] = -1; // tag sdu as non valid - // we can remove the sdu if timer based discard and all pdus submitted to lower layers and no confirm running - free_mem_block (sdu); - rlcP->input_sdus[sdu_index] = NULL; -# ifdef DEBUG_RLC_AM_FREE_SDU - msg ("[RLC_AM][RB %d] MUX FREE_SDU INDEX %d\n", rlcP->rb_id, sdu_index); -# endif - - } else { - ((struct rlc_am_tx_sdu_management*) (sdu->data))->last_pdu_sn = rlcP->vt_s; - } - } - - } else if ((rlcP->sdu_discard_mode & RLC_SDU_DISCARD_MAX_DAT_RETRANSMISSION)) { - for (index = 0; index < ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->nb_sdu; index++) { - // update the sn of the last transmitted pdu were this sdu was segmented - ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[((struct rlc_am_tx_data_pdu_management*) (pdu->data))->sdu[index]]->data))->last_pdu_sn = rlcP->vt_s; - // register the sn of the pdus where the sdu was segmented - ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[((struct rlc_am_tx_data_pdu_management*) (pdu->data))->sdu[index]]->data))-> - pdus_index[((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[((struct rlc_am_tx_data_pdu_management*) ( - pdu->data))->sdu[index]]->data))->nb_pdus_internal_use++] = rlcP->vt_s; -# ifdef DEBUG_MUX - msg ("[RLC_AM][RB %d] MUX SDU INDEX %d LINK PDU SN 0x%04X\n", rlcP->rb_id, ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->sdu[index], rlcP->vt_s); -# endif - } - } - - rlcP->vt_s = (rlcP->vt_s + 1) & SN_12BITS_MASK; - copy_pdu = get_free_mem_block (rlcP->pdu_size + sizeof (struct rlc_am_tx_data_pdu_allocation) + GUARD_CRC_LIH_SIZE); - - if (copy_pdu) { - memcpy (copy_pdu->data, pdu->data, rlcP->pdu_size + sizeof (struct rlc_am_tx_data_pdu_allocation)); -# ifdef DEBUG_MUX - rlc_am_display_data_pdu7(pdu); -# endif - ((struct mac_tb_req*) (copy_pdu->data))->rlc_tb_type = ((struct rlc_am_tx_data_pdu_management*) (copy_pdu->data))->rlc_tb_type; - ((struct mac_tb_req*) (copy_pdu->data))->rlc = rlcP; - ((struct mac_tb_req*) (copy_pdu->data))->rlc_callback = rlc_am_status_report_from_mac; - ((struct mac_tb_req*) (copy_pdu->data))->data_ptr = ©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]; - ((struct mac_tb_req*) (copy_pdu->data))->first_bit = 0; - ((struct mac_tb_req*) (copy_pdu->data))->tb_size_in_bits = rlcP->pdu_size << 3; - list_add_tail_eurecom (copy_pdu, &rlcP->pdus_to_mac_layer_ch1); - nb_pdu_to_transmit_ch1--; - data_pdu_tx++; -# ifdef DEBUG_MUX - id = (((uint16_t) (rlc_header->byte1 & RLC_AM_SN_1ST_PART_MASK)) << 5) | ((rlc_header->byte2 & RLC_AM_SN_2ND_PART_MASK) >> 3); - msg ("[RLC_AM][RB %d][MUX] TX DATA PDU 0x%04X VT(A) 0x%03X VT(S) 0x%03X VT(MS) 0x%03X VR(R) 0x%03X VR(MR) 0x%03X\n", - rlcP->rb_id, id, rlcP->vt_a, rlcP->vt_s, rlcP->vt_ms, rlcP->vr_r, rlcP->vr_mr); - /* for (index = 0; index < 32 ; index++) { - msg("%02X.", pdu->data[index]); - } - msg("\n"); - */ -# endif - - } else { - msg ("[RLC_AM][RB %d][MUX] OUT OF MEMORY \n", rlcP->rb_id); - } - - } else { // segmentation returned no PDU - segmentation_returned_pdu = 0; - } - } - } - - // From 3GPP TS 25.322 V5.0.0 (2002-03) - // - if a poll has been triggered by either the poll triggers "Poll timer" or "Timer based" (see subclause 9.7.1); - // AND - // - if no AMD PDU is scheduled for transmission or retransmission: - // - if the value of "Configured_Tx_Window_Size" is larger than or equal to "2048": - // - select the AMD PDU with "Sequence Number" equal to VT(S)-1. - // - otherwise if the "Configured_Tx_Window_Size" is less than "2048"; - // - select the AMD PDU with "Sequence Number" equal to VT(S)-1; or - // - select an AMD PDU that has not yet been acknowledged by the peer entity; - // - schedule the selected AMD PDU for retransmission (in order to transmit a poll). - // The Sender may also schedule an AMD PDU for retransmission even if none of the criteria above is fulfilled. In this case, the Sender may: - // - if the value of "Configured_Tx_Window_Size" is larger than or equal to "2048": - // - select the AMD PDU with "Sequence Number" equal to VT(S)-1. - // - otherwise if the "Configured_Tx_Window_Size" is less than "2048": - // - select the AMD PDU with "Sequence Number" equal to VT(S)-1; or - // - select an AMD PDU that has not yet been acknowledged by the peer entity; - // - schedule the selected AMD PDU for retransmission. - // TO DO : triggers "Poll timer" or "Timer based" - if (!(data_pdu_tx)) { - if (rlcP->configured_tx_window_size < 2048) { - rlc_am_get_not_acknowledged_pdu_optimized (rlcP); - - } else if (rlcP->vt_s != rlcP->vt_a) { - rlc_am_get_not_acknowledged_pdu_optimized (rlcP);//rlc_am_get_not_acknowledged_pdu_vt_s_minus_1 (rlcP); - } - - // each retransmission may send RLC in RESET STATE if no discard is configured - copy_pdu = list2_remove_head (&rlcP->retransmission_buffer_to_send); - - if ((copy_pdu)) { - // unlink the pdu in retransmission buffer and its copy (mechanism avoiding multi-retransmission of the same - // pdu in the same queue) - pdu = ((struct rlc_am_tx_data_pdu_management*) (copy_pdu->data))->copy; -# ifdef DEBUG_MUX - rlc_am_display_data_pdu7(copy_pdu); -# endif - ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->copy = NULL; - ((struct mac_tb_req*) (copy_pdu->data))->rlc_tb_type = ((struct rlc_am_tx_data_pdu_management*) (copy_pdu->data))->rlc_tb_type; - ((struct mac_tb_req*) (copy_pdu->data))->rlc = rlcP; - ((struct mac_tb_req*) (copy_pdu->data))->rlc_callback = rlc_am_status_report_from_mac; - ((struct mac_tb_req*) (copy_pdu->data))->data_ptr = ©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]; - ((struct mac_tb_req*) (copy_pdu->data))->first_bit = 0; - ((struct mac_tb_req*) (copy_pdu->data))->tb_size_in_bits = rlcP->pdu_size << 3; - list_add_tail_eurecom (copy_pdu, &rlcP->pdus_to_mac_layer_ch1); - nb_pdu_to_transmit_ch1--; - data_pdu_tx++; - // for polling - rlcP->vt_pdu++; - // set poll bit - ((struct rlc_am_pdu_header*) (©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2 |= RLC_AM_P_STATUS_REPORT_REQUESTED; -# ifdef DEBUG_MUX - id = (((uint16_t) (((struct rlc_am_pdu_header*) (©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte1 & RLC_AM_SN_1ST_PART_MASK)) << 5) | - ((((struct rlc_am_pdu_header*) (©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2 & RLC_AM_SN_2ND_PART_MASK) >> 3); - msg ("[RLC_AM][RB %d][MUX] RETRANSMIT DATA PDU 0x%04X VT(A) 0x%03X VT(S) 0x%03X VT(MS) 0x%03X VR(R) 0x%03X VR(MR) 0x%03X\n", - rlcP->rb_id, id, rlcP->vt_a, rlcP->vt_s, rlcP->vt_ms, rlcP->vr_r, rlcP->vr_mr); -# endif - } - } - } -} -#endif -#ifdef NODE_RG -//#define DEBUG_MUX -/* - * mux PDUs from segmentation buffer and PDUs from retransmission buffer - * onto transmission buffer - */ -//----------------------------------------------------------------------------- -void -rlc_am_mux_rg (struct rlc_am_entity* rlcP, unsigned int traffic_typeP) -{ - //----------------------------------------------------------------------------- - mem_block_t* pdu; - mem_block_t* sdu; - mem_block_t* copy_pdu = NULL; - struct rlc_am_pdu_header* rlc_header; - int pool_is_set; - int index; - int sdu_index; - unsigned int j, segmentation_returned_pdu; - unsigned int data_pdu_tx; // data pdu effectively transmitted - unsigned int tx_pdu; - static unsigned int last_scheduled; - int16_t nb_pdu_to_transmit_ch1; - int16_t nb_pdu_to_transmit_ch2; -# ifdef DEBUG_MUX - uint16_t id; -# endif - data_pdu_tx = 0; - nb_pdu_to_transmit_ch1 = rlcP->nb_pdu_requested_by_mac_on_ch1; - nb_pdu_to_transmit_ch2 = rlcP->nb_pdu_requested_by_mac_on_ch2; - - // discard - if ((rlcP->sdu_discarded.head) && (traffic_typeP & RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS)) { - rlc_am_process_sdu_discarded (rlcP); - } - - // from TS25.322 V4.2.0 p13 - // In case two logical channels are configured in the downlink, AMD and Control - // PDUs can be transmitted on any of the two logical channels. - /****************************************** - * CONTROL PDU * - ******************************************/ - if (rlcP->nb_logical_channels_per_rlc == 1) { - while ((rlcP->control.head) && (nb_pdu_to_transmit_ch1)) { - pdu = list_remove_head (&rlcP->control); - - if ((traffic_typeP & RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS)) { - tx_pdu = 1; - - } else { - if (((struct rlc_am_tx_control_pdu_management*) (pdu->data))->rlc_tb_type & (RLC_AM_RESET_PDU_TYPE | RLC_AM_RESET_ACK_PDU_TYPE)) { - tx_pdu = 1; - - } else { - tx_pdu = 0; - } - } - - if ((tx_pdu)) { - nb_pdu_to_transmit_ch1--; - // for polling - rlcP->vt_pdu++; - ((struct mac_tb_req*) (pdu->data))->rlc_tb_type = ((struct rlc_am_tx_control_pdu_management*) (pdu->data))->rlc_tb_type; - ((struct mac_tb_req*) (pdu->data))->rlc = rlcP; - ((struct mac_tb_req*) (pdu->data))->rlc_callback = rlc_am_status_report_from_mac; - ((struct mac_tb_req*) (pdu->data))->data_ptr = &pdu->data[sizeof (struct rlc_am_tx_control_pdu_allocation)]; - ((struct mac_tb_req*) (pdu->data))->first_bit = 0; - ((struct mac_tb_req*) (pdu->data))->tb_size_in_bits = rlcP->pdu_size << 3; - list_add_tail_eurecom (pdu, &rlcP->pdus_to_mac_layer_ch1); - rlcP->stat_tx_control_pdu += 1; -# ifdef DEBUG_MUX - msg ("[RLC_AM][RB %d][MUX] TX CONTROL PDU CH1 VT(A) 0x%03X VT(S) 0x%03X VT(MS) 0x%03X VR(R) 0x%03X VR(MR) 0x%03X\n", - rlcP->rb_id, rlcP->vt_a, rlcP->vt_s, rlcP->vt_ms, rlcP->vr_r, rlcP->vr_mr); -# endif - - } else { - free_mem_block (pdu); - } - } - - } else if (rlcP->nb_logical_channels_per_rlc == 2) { - while ((rlcP->control.head) && (nb_pdu_to_transmit_ch2)) { - pdu = list_remove_head (&rlcP->control); - - if ((traffic_typeP & RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS)) { - tx_pdu = 1; - - } else { - if (((struct rlc_am_tx_control_pdu_management*) (pdu->data))->rlc_tb_type & (RLC_AM_RESET_PDU_TYPE | RLC_AM_RESET_ACK_PDU_TYPE)) { - tx_pdu = 1; - - } else { - tx_pdu = 0; - } - } - - if ((tx_pdu)) { - nb_pdu_to_transmit_ch2--; - // for polling - rlcP->vt_pdu++; - ((struct mac_tb_req*) (pdu->data))->rlc_tb_type = ((struct rlc_am_tx_control_pdu_management*) (pdu->data))->rlc_tb_type; - ((struct mac_tb_req*) (pdu->data))->rlc = rlcP; - ((struct mac_tb_req*) (pdu->data))->rlc_callback = rlc_am_status_report_from_mac; - ((struct mac_tb_req*) (pdu->data))->data_ptr = &pdu->data[sizeof (struct rlc_am_tx_control_pdu_allocation)]; - ((struct mac_tb_req*) (pdu->data))->first_bit = 0; - ((struct mac_tb_req*) (pdu->data))->tb_size_in_bits = rlcP->pdu_size << 3; - list_add_tail_eurecom (pdu, &rlcP->pdus_to_mac_layer_ch2); - rlcP->stat_tx_control_pdu += 1; -# ifdef DEBUG_MUX - msg ("[RLC_AM][RB %d][MUX] TX CONTROL PDU CH2 VT(A) 0x%03X VT(S) 0x%03X VT(MS) 0x%03X VR(R) 0x%03X VR(MR) 0x%03X\n", - rlcP->rb_id, rlcP->vt_a, rlcP->vt_s, rlcP->vt_ms, rlcP->vr_r, rlcP->vr_mr); -# endif - - } else { - free_mem_block (pdu); - } - } - - while ((rlcP->control.head) && (nb_pdu_to_transmit_ch1)) { - pdu = list_remove_head (&rlcP->control); - - if ((traffic_typeP & RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS)) { - tx_pdu = 1; - - } else { - if (((struct rlc_am_tx_control_pdu_management*) (pdu->data))->rlc_tb_type & (RLC_AM_RESET_PDU_TYPE | RLC_AM_RESET_ACK_PDU_TYPE)) { - tx_pdu = 1; - - } else { - tx_pdu = 0; - } - } - - if ((tx_pdu)) { - nb_pdu_to_transmit_ch1--; - // for polling - rlcP->vt_pdu++; - ((struct mac_tb_req*) (pdu->data))->rlc_tb_type = ((struct rlc_am_tx_control_pdu_management*) (copy_pdu->data))->rlc_tb_type; - ((struct mac_tb_req*) (pdu->data))->rlc = rlcP; - ((struct mac_tb_req*) (pdu->data))->rlc_callback = rlc_am_status_report_from_mac; - ((struct mac_tb_req*) (pdu->data))->data_ptr = &pdu->data[sizeof (struct rlc_am_tx_control_pdu_allocation)]; - ((struct mac_tb_req*) (pdu->data))->first_bit = 0; - ((struct mac_tb_req*) (pdu->data))->tb_size_in_bits = rlcP->pdu_size << 3; - list_add_tail_eurecom (pdu, &rlcP->pdus_to_mac_layer_ch1); - rlcP->stat_tx_control_pdu += 1; -# ifdef DEBUG_MUX - msg ("[RLC_AM][RB %d][MUX] TX CONTROL PDU CH1 VT(A) 0x%03X VT(S) 0x%03X VT(MS) 0x%03X VR(R) 0x%03X VR(MR) 0x%03X\n", - rlcP->rb_id, rlcP->vt_a, rlcP->vt_s, rlcP->vt_ms, rlcP->vr_r, rlcP->vr_mr); -# endif - - } else { - free_mem_block (pdu); - } - } - } - - if (traffic_typeP & RLC_AM_TRAFFIC_ALLOWED_FOR_DATA) { - /****************************************** - * RETRANSMITED DATA PDU * - ******************************************/ - while ((rlcP->retransmission_buffer_to_send.head) && (nb_pdu_to_transmit_ch1) && !(rlcP->protocol_state & RLC_RESET_PENDING_STATE)) { - // each retransmission may send RLC in RESET STATE if no discard is configured - copy_pdu = list2_remove_head (&rlcP->retransmission_buffer_to_send); - // unlink the pdu in retransmission buffer and its copy (mechanism avoiding multi-retransmission of the same - // pdu in the same queue) - pdu = ((struct rlc_am_tx_data_pdu_management*) (copy_pdu->data))->copy; -# ifdef DEBUG_MUX - rlc_am_display_data_pdu7(copy_pdu); -# endif - ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->copy = NULL; - ((struct mac_tb_req*) (copy_pdu->data))->rlc_tb_type = ((struct rlc_am_tx_data_pdu_management*) (copy_pdu->data))->rlc_tb_type; - ((struct mac_tb_req*) (copy_pdu->data))->rlc = rlcP; - ((struct mac_tb_req*) (copy_pdu->data))->rlc_callback = rlc_am_status_report_from_mac; - ((struct mac_tb_req*) (copy_pdu->data))->data_ptr = ©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]; - ((struct mac_tb_req*) (copy_pdu->data))->first_bit = 0; - ((struct mac_tb_req*) (copy_pdu->data))->tb_size_in_bits = rlcP->pdu_size << 3; - list_add_tail_eurecom (copy_pdu, &rlcP->pdus_to_mac_layer_ch1); - rlcP->stat_tx_retransmit_pdu += 1; - nb_pdu_to_transmit_ch1--; - data_pdu_tx++; - - // for polling - if (rlcP->poll_pdu_trigger) { - rlcP->vt_pdu++; - - if (rlcP->vt_pdu >= rlcP->poll_pdu_trigger) { - // set poll bit - ((struct rlc_am_pdu_header*) (©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2 |= RLC_AM_P_STATUS_REPORT_REQUESTED; - rlcP->vt_pdu = 0; - - } else { - // reset poll bit - ((struct rlc_am_pdu_header*) (©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2 = - ((struct rlc_am_pdu_header*) (©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2 & ~RLC_AM_P_STATUS_REPORT_REQUESTED; - } - } - -# ifdef DEBUG_MUX - id = (((uint16_t) (((struct rlc_am_pdu_header*) (©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte1 & RLC_AM_SN_1ST_PART_MASK)) << 5) | - ((((struct rlc_am_pdu_header*) (©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2 & RLC_AM_SN_2ND_PART_MASK) >> 3); - msg ("[RLC_AM][RB %d][MUX] RETRANSMIT DATA PDU %04X VT(A) 0x%03X VT(S) 0x%03X VT(MS) 0x%03X VR(R) 0x%03X VR(MR) 0x%03X\n", - rlcP->rb_id, id, rlcP->vt_a, rlcP->vt_s, rlcP->vt_ms, rlcP->vr_r, rlcP->vr_mr); -# endif - } - - while ((rlcP->retransmission_buffer_to_send.head) && (nb_pdu_to_transmit_ch2) && !(rlcP->protocol_state & RLC_RESET_PENDING_STATE)) { - // each retransmission may send RLC in RESET STATE if no discard is configured - copy_pdu = list2_remove_head (&rlcP->retransmission_buffer_to_send); - // unlink the pdu in retransmission buffer and its copy (mechanism avoiding multi-retransmission of the same - // pdu in the same queue) - pdu = ((struct rlc_am_tx_data_pdu_management*) (copy_pdu->data))->copy; -# ifdef DEBUG_MUX - rlc_am_display_data_pdu7(copy_pdu); -# endif - ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->copy = NULL; - ((struct mac_tb_req*) (copy_pdu->data))->rlc_tb_type = ((struct rlc_am_tx_data_pdu_management*) (copy_pdu->data))->rlc_tb_type; - ((struct mac_tb_req*) (copy_pdu->data))->rlc = rlcP; - ((struct mac_tb_req*) (copy_pdu->data))->rlc_callback = rlc_am_status_report_from_mac; - ((struct mac_tb_req*) (copy_pdu->data))->data_ptr = ©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]; - ((struct mac_tb_req*) (copy_pdu->data))->first_bit = 0; - ((struct mac_tb_req*) (copy_pdu->data))->tb_size_in_bits = rlcP->pdu_size << 3; - list_add_tail_eurecom (copy_pdu, &rlcP->pdus_to_mac_layer_ch2); - rlcP->stat_tx_retransmit_pdu += 1; - nb_pdu_to_transmit_ch2--; - data_pdu_tx++; - - // for polling - if (rlcP->poll_pdu_trigger) { - rlcP->vt_pdu++; - - if (rlcP->vt_pdu >= rlcP->poll_pdu_trigger) { - // set poll bit -# ifdef DEBUG_RLC_AM_POLL - msg ("[RLC_AM %p] POOL SET BY poll_pdu trigger RETRANS PDU\n", rlcP); -# endif - ((struct rlc_am_pdu_header*) (©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2 |= RLC_AM_P_STATUS_REPORT_REQUESTED; - rlcP->vt_pdu = 0; - - } else { - // reset poll bit - ((struct rlc_am_pdu_header*) (©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2 = - ((struct rlc_am_pdu_header*) (©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2 & ~RLC_AM_P_STATUS_REPORT_REQUESTED; - } - } - -# ifdef DEBUG_MUX - id = (((uint16_t) (((struct rlc_am_pdu_header*) (©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte1 & RLC_AM_SN_1ST_PART_MASK)) << 5) | - ((((struct rlc_am_pdu_header*) (©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2 & RLC_AM_SN_2ND_PART_MASK) >> 3); - msg ("[RLC_AM][RB %d][MUX] RETRANSMIT DATA PDU 0x%04X VT(A) 0x%03X VT(S) 0x%03X VT(MS) 0x%03X VR(R) 0x%03X VR(MR) 0x%03X\n", - rlcP->rb_id, id, rlcP->vt_a, rlcP->vt_s, rlcP->vt_ms, rlcP->vr_r, rlcP->vr_mr); -# endif - } - - /****************************************** - * DATA PDU * - ******************************************/ - if (!(rlcP->protocol_state & RLC_RESET_PENDING_STATE)) { - segmentation_returned_pdu = 1; - - while (((nb_pdu_to_transmit_ch1) || (nb_pdu_to_transmit_ch2)) && (rlcP->vt_s != rlcP->vt_ms) && (segmentation_returned_pdu)) { - if ((pdu = rlcP->rlc_segment (rlcP))) { - rlc_header = (struct rlc_am_pdu_header*) (&pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]); - // check polling - pool_is_set = 0; - - if (rlcP->poll_pdu_trigger) { - rlcP->vt_pdu++; - - // test every poll_PDU trigger - if (rlcP->vt_pdu >= rlcP->poll_pdu_trigger) { - ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->rlc_tb_type = RLC_AM_DATA_POLL_PDU_TYPE; - ((struct rlc_am_pdu_header*) (&pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2 |= RLC_AM_P_STATUS_REPORT_REQUESTED; - rlcP->vt_pdu = 0; - pool_is_set = 1; -# ifdef DEBUG_RLC_AM_POLL - msg ("[RLC_AM %p] POOL SET BY poll_pdu trigger\n", rlcP); -# endif - } - } - - // test every poll_SDU trigger - if ((rlcP->poll_sdu_trigger) && (((struct rlc_am_tx_data_pdu_management*) (pdu->data))->last_pdu_of_sdu)) { - if (rlcP->vt_sdu >= rlcP->poll_sdu_trigger) { - ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->rlc_tb_type = RLC_AM_DATA_POLL_PDU_TYPE; - ((struct rlc_am_pdu_header*) (&pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2 |= RLC_AM_P_STATUS_REPORT_REQUESTED; - rlcP->vt_sdu = 0; - pool_is_set = 1; -# ifdef DEBUG_RLC_AM_POLL - msg ("[RLC_AM %p] POOL SET BY poll_sdu trigger\n", rlcP); -# endif - - } else { - rlcP->vt_sdu += ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->last_pdu_of_sdu; - } - } - - if (!pool_is_set) { - // test last pdu in transmission buffer trigger == last sdu in input buffer in this implementation of RLC AM - if ((rlcP->last_transmission_pdu_poll_trigger > 0) && (rlcP->nb_sdu == 0)) { - ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->rlc_tb_type = RLC_AM_DATA_POLL_PDU_TYPE; - ((struct rlc_am_pdu_header*) (&pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2 |= RLC_AM_P_STATUS_REPORT_REQUESTED; - pool_is_set = 1; -# ifdef DEBUG_RLC_AM_POLL - msg ("[RLC_AM %p] POOL SET BY last pdu in tr buffer trigger\n", rlcP); -# endif - } - - if (!pool_is_set) { - // test last pdu in retransmission buffer trigger - if ((rlcP->retransmission_buffer_to_send.head) && (rlcP->retransmission_buffer_to_send.head == rlcP->retransmission_buffer_to_send.tail) - && (rlcP->last_retransmission_pdu_poll_trigger)) { - ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->rlc_tb_type = RLC_AM_DATA_POLL_PDU_TYPE; - ((struct rlc_am_pdu_header*) (&pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2 |= RLC_AM_P_STATUS_REPORT_REQUESTED; - pool_is_set = 1; -# ifdef DEBUG_RLC_AM_POLL - msg ("[RLC_AM %p] POOL SET BY last pdu in retrans buffer trigger\n", rlcP); -# endif - } - - if (!pool_is_set) { - // test window based trigger - if (rlcP->poll_window_trigger) { - j = (unsigned int) (((rlcP->vt_s + 4096) - rlcP->vt_a) % 4096) * 100 / rlcP->vt_ws; - - if (j >= rlcP->poll_window_trigger) { - ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->rlc_tb_type = RLC_AM_DATA_POLL_PDU_TYPE; - ((struct rlc_am_pdu_header*) (&pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2 |= RLC_AM_P_STATUS_REPORT_REQUESTED; - pool_is_set = 1; -# ifdef DEBUG_RLC_AM_POLL - msg ("[RLC_AM %p] POOL SET BY window based trigger J=%d\n", rlcP, j); -# endif - } - } - } - } - } - - rlc_header->byte1 |= (rlcP->vt_s >> 5); - rlc_header->byte2 |= ((uint8_t) rlcP->vt_s << 3); - ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->sn = rlcP->vt_s; - insert_into_retransmission_buffer (rlcP, rlcP->vt_s % rlcP->recomputed_configured_tx_window_size, pdu); - - // check if timer based discard configured - if ((rlcP->sdu_discard_mode & RLC_SDU_DISCARD_TIMER_BASED_EXPLICIT)) { - for (index = 0; index < ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->nb_sdu; index++) { - sdu_index = ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->sdu[index]; - sdu = rlcP->input_sdus[sdu_index]; - - // mark the sdu as invalid except if confirm requested - if (!((struct rlc_am_tx_sdu_management*) (sdu->data))->confirm) { - ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->sdu[index] = -1; // tag sdu as non valid - } - - ((struct rlc_am_tx_sdu_management*) (sdu->data))->nb_pdus_time += 1; - - if ((((struct rlc_am_tx_sdu_management*) (sdu->data))->nb_pdus_time == - ((struct rlc_am_tx_sdu_management*) (sdu->data))->nb_pdus) && - !(((struct rlc_am_tx_sdu_management*) (sdu->data))->confirm) && (((struct rlc_am_tx_sdu_management*) (sdu->data))->segmented) - ) { - ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->sdu[index] = -1; // tag sdu as non valid - // we can remove the sdu if timer based discard and all pdus submitted to lower layers and no confirm running - free_mem_block (sdu); - rlcP->input_sdus[sdu_index] = NULL; -# ifdef DEBUG_RLC_AM_FREE_SDU - msg ("[RLC_AM][RB %d] MUX FREE_SDU INDEX %d\n", rlcP->rb_id, sdu_index); -# endif - - } else { - ((struct rlc_am_tx_sdu_management*) (sdu->data))->last_pdu_sn = rlcP->vt_s; - } - } - - } else if ((rlcP->sdu_discard_mode & RLC_SDU_DISCARD_MAX_DAT_RETRANSMISSION)) { - for (index = 0; index < ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->nb_sdu; index++) { - // update the sn of the last transmitted pdu were this sdu was segmented - ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[((struct rlc_am_tx_data_pdu_management*) (pdu->data))->sdu[index]]->data))->last_pdu_sn = rlcP->vt_s; - // register the sn of the pdus where the sdu was segmented - ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[((struct rlc_am_tx_data_pdu_management*) (pdu->data))->sdu[index]]->data))-> - pdus_index[((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[((struct rlc_am_tx_data_pdu_management*) ( - pdu->data))->sdu[index]]->data))->nb_pdus_internal_use++] = rlcP->vt_s; -# ifdef DEBUG_MUX - msg ("[RLC_AM][RB %d] MUX SDU INDEX %d LINK PDU SN 0x%04X\n", rlcP->rb_id, ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->sdu[index], rlcP->vt_s); -# endif - } - } - - rlcP->vt_s = (rlcP->vt_s + 1) & SN_12BITS_MASK; - copy_pdu = get_free_mem_block (rlcP->pdu_size + sizeof (struct rlc_am_tx_data_pdu_allocation) + GUARD_CRC_LIH_SIZE); - - if (copy_pdu) { - memcpy (copy_pdu->data, pdu->data, rlcP->pdu_size + sizeof (struct rlc_am_tx_data_pdu_allocation)); -# ifdef DEBUG_MUX - rlc_am_display_data_pdu7(copy_pdu); -# endif - ((struct mac_tb_req*) (copy_pdu->data))->rlc_tb_type = ((struct rlc_am_tx_data_pdu_management*) (copy_pdu->data))->rlc_tb_type; - ((struct mac_tb_req*) (copy_pdu->data))->rlc = rlcP; - ((struct mac_tb_req*) (copy_pdu->data))->rlc_callback = rlc_am_status_report_from_mac; - ((struct mac_tb_req*) (copy_pdu->data))->data_ptr = ©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]; - ((struct mac_tb_req*) (copy_pdu->data))->first_bit = 0; - ((struct mac_tb_req*) (copy_pdu->data))->tb_size_in_bits = rlcP->pdu_size << 3; - - if ((nb_pdu_to_transmit_ch1)) { - list_add_tail_eurecom (copy_pdu, &rlcP->pdus_to_mac_layer_ch1); - rlcP->stat_tx_data_pdu += 1; - nb_pdu_to_transmit_ch1--; - - } else if ((nb_pdu_to_transmit_ch2)) { - list_add_tail_eurecom (copy_pdu, &rlcP->pdus_to_mac_layer_ch2); - rlcP->stat_tx_data_pdu += 1; - nb_pdu_to_transmit_ch2--; - } - - data_pdu_tx++; -# ifdef DEBUG_MUX - id = (((uint16_t) (((struct rlc_am_pdu_header*) (&pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte1 & RLC_AM_SN_1ST_PART_MASK)) << 5) | - ((((struct rlc_am_pdu_header*) (&pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2 & RLC_AM_SN_2ND_PART_MASK) >> 3); - msg ("[RLC_AM][RB %d][MUX] TX DATA PDU 0x%04X VT(A) 0x%03X VT(S) 0x%03X VT(MS) 0x%03X VR(R) 0x%03X VR(MR) 0x%03X\n", - rlcP->rb_id, id, rlcP->vt_a, rlcP->vt_s, rlcP->vt_ms, rlcP->vr_r, rlcP->vr_mr); - /* for (index = 0; index < 32 ; index++) { - msg("%02X.", pdu->data[index]); - } - msg("\n"); - */ -# endif - - } else { - msg ("[RLC_AM][RB %d][MUX] OUT OF MEMORY \n", rlcP->rb_id); - } - - } else { // segmentation returned no PDU - segmentation_returned_pdu = 0; - } - } - } - - // From 3GPP TS 25.322 V5.0.0 (2001-09) - // - if a poll has been triggered by either the poll triggers "Poll timer" or "Timer based" (see subclause 9.7.1); - // AND - // - if no AMD PDU is scheduled for transmission or retransmission: - // - if the value of "Configured_Tx_Window_Size" is larger than or equal to "2048": - // - select the AMD PDU with "Sequence Number" equal to VT(S)-1. - // - otherwise if the "Configured_Tx_Window_Size" is less than "2048"; - // - select the AMD PDU with "Sequence Number" equal to VT(S)-1; or - // - select an AMD PDU that has not yet been acknowledged by the peer entity; - // - schedule the selected AMD PDU for retransmission (in order to transmit a poll). - // The Sender may also schedule an AMD PDU for retransmission even if none of the criteria above is fulfilled. In this case, the Sender may: - // - if the value of "Configured_Tx_Window_Size" is larger than or equal to "2048": - // - select the AMD PDU with "Sequence Number" equal to VT(S)-1. - // - otherwise if the "Configured_Tx_Window_Size" is less than "2048": - // - select the AMD PDU with "Sequence Number" equal to VT(S)-1; or - // - select an AMD PDU that has not yet been acknowledged by the peer entity; - // - schedule the selected AMD PDU for retransmission. - // TO DO : triggers "Poll timer" or "Timer based" - if (!(data_pdu_tx)) { - // this variable last_scheduled is used because a RLC may be scheduled - // when several DSCH are configured in the RG - if ((last_scheduled != (unsigned int) Mac_rlc_xface->frame) && (((unsigned int) Mac_rlc_xface->frame) % 48 == 0) ) { - if (rlcP->configured_tx_window_size < 2048) { - // rlc_am_get_not_acknowledged_pdu(rlcP); - rlc_am_get_not_acknowledged_pdu_optimized (rlcP); - //rlc_am_get_not_acknowledged_pdu_vt_s_minus_1 (rlcP); // LG JUST FOR TEST - - } else if (rlcP->vt_s != rlcP->vt_a) { - rlc_am_get_not_acknowledged_pdu_optimized (rlcP);//rlc_am_get_not_acknowledged_pdu_vt_s_minus_1 (rlcP); - } - } - - last_scheduled = (unsigned int) Mac_rlc_xface->frame; - // each retransmission may send RLC in RESET STATE if no discard is configured - copy_pdu = list2_remove_head (&rlcP->retransmission_buffer_to_send); - - if ((copy_pdu)) { - // unlink the pdu in retransmission buffer and its copy (mechanism avoiding multi-retransmission of the same - // pdu in the same queue) - pdu = ((struct rlc_am_tx_data_pdu_management*) (copy_pdu->data))->copy; -# ifdef DEBUG_MUX - rlc_am_display_data_pdu7(copy_pdu); -# endif - ((struct rlc_am_tx_data_pdu_management*) (pdu->data))->copy = NULL; - ((struct mac_tb_req*) (copy_pdu->data))->rlc_tb_type = ((struct rlc_am_tx_data_pdu_management*) (copy_pdu->data))->rlc_tb_type; - ((struct mac_tb_req*) (copy_pdu->data))->rlc = rlcP; - ((struct mac_tb_req*) (copy_pdu->data))->rlc_callback = rlc_am_status_report_from_mac; - ((struct mac_tb_req*) (copy_pdu->data))->data_ptr = ©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]; - ((struct mac_tb_req*) (copy_pdu->data))->first_bit = 0; - ((struct mac_tb_req*) (copy_pdu->data))->tb_size_in_bits = rlcP->pdu_size << 3; - list_add_tail_eurecom (copy_pdu, &rlcP->pdus_to_mac_layer_ch1); - rlcP->stat_tx_retransmit_pdu += 1; - nb_pdu_to_transmit_ch1--; - data_pdu_tx++; - // for polling - rlcP->vt_pdu++; - // set poll bit - ((struct rlc_am_pdu_header*) (©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2 |= RLC_AM_P_STATUS_REPORT_REQUESTED; -# ifdef DEBUG_MUX - id = (((uint16_t) (((struct rlc_am_pdu_header*) (©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte1 & RLC_AM_SN_1ST_PART_MASK)) << 5) | - ((((struct rlc_am_pdu_header*) (©_pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]))->byte2 & RLC_AM_SN_2ND_PART_MASK) >> 3); - msg ("[RLC_AM][RB %d][MUX] RETRANSMIT DATA PDU 0x%04X VT(A) 0x%03X VT(S) 0x%03X VT(MS) 0x%03X VR(R) 0x%03X VR(MR) 0x%03X\n", - rlcP->rb_id, id, rlcP->vt_a, rlcP->vt_s, rlcP->vt_ms, rlcP->vr_r, rlcP->vr_mr); -# endif - } - } - } -} -#endif diff --git a/openair2/LAYER2/RLC/AM/rlc_am_mux_proto_extern.h b/openair2/LAYER2/RLC/AM/rlc_am_mux_proto_extern.h deleted file mode 100755 index ef30199d1f8fe12f298b7e027ca09f7a412ef3b9..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_mux_proto_extern.h +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_mux_proto_extern.h - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - ***************************************************************************/ -# ifndef __RLC_AM_MUX_PROTO_EXTERN_H__ -# define __RLC_AM_MUX_PROTO_EXTERN_H__ -//----------------------------------------------------------------------------- -# include "rlc_am_entity.h" -# include "rlc_am_structs.h" -# include "rlc_am_constants.h" -//----------------------------------------------------------------------------- -# ifdef NODE_MT -extern void rlc_am_mux_ue (struct rlc_am_entity *rlcP, unsigned int traffic_typeP); -# endif -# ifdef NODE_RG -extern void rlc_am_mux_rg (struct rlc_am_entity *rlcP, unsigned int traffic_typeP); -# endif -# endif diff --git a/openair2/LAYER2/RLC/AM/rlc_am_proto_extern.h b/openair2/LAYER2/RLC/AM/rlc_am_proto_extern.h deleted file mode 100755 index 90913bcbf5029d48acefc25a62acf889113da50f..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_proto_extern.h +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_proto_extern.h - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - ***************************************************************************/ -# ifndef __RLC_AM_PROTO_EXTERN_H__ -# define __RLC_AM_PROTO_EXTERN_H__ -//----------------------------------------------------------------------------- -# include "platform_types.h" -# include "platform_constants.h" -# include "list.h" -# include "rlc_am_entity.h" -# include "mac_primitives.h" -# include "mem_block.h" -//----------------------------------------------------------------------------- -extern void display_protocol_vars_rlc_am (struct rlc_am_entity *rlcP); -extern uint32_t rlc_am_get_buffer_occupancy (struct rlc_am_entity *rlcP, uint8_t logical_channelsP); -extern void init_rlc_am (struct rlc_am_entity *rlcP); -extern void *rlc_am_tx (void *argP); -extern void rlc_am_rx (void *argP, struct mac_data_ind data_indP); -extern void *init_code_rlc_am (void *t); -extern void send_rlc_am_control_primitive (struct rlc_am_entity *rlcP, module_id_t module_idP, mem_block_t * cprimitiveP); -extern void rlc_am_send_mac_data_request (void *macP, uint8_t logical_channel_identityP, list_t * pduP); - -extern struct mac_status_resp rlc_am_mac_status_indication (void *rlcP, uint16_t no_tbP, uint16_t tb_sizeP, struct mac_status_ind tx_statusP); -extern struct mac_status_resp rlc_am_mac_status_indication_on_first_channel (void *rlcP, uint16_t no_tbP, uint16_t tb_sizeP, struct mac_status_ind tx_statusP); -extern struct mac_status_resp rlc_am_mac_status_indication_on_second_channel (void *rlcP, uint16_t no_tbP, uint16_t tb_sizeP, struct mac_status_ind tx_statusP); -extern struct mac_data_req rlc_am_mac_data_request (void *rlcP); -extern struct mac_data_req rlc_am_mac_data_request_on_first_channel (void *rlcP); -extern struct mac_data_req rlc_am_mac_data_request_on_second_channel (void *rlcP); -extern void rlc_am_mac_data_indication (void *rlcP, struct mac_data_ind data_indP); -extern void rlc_am_data_req (void *rlcP, mem_block_t * sduP); -# endif diff --git a/openair2/LAYER2/RLC/AM/rlc_am_reassembly.c b/openair2/LAYER2/RLC/AM/rlc_am_reassembly.c deleted file mode 100755 index 897054602666f4b8e8ea59228ca3ea5bd3d0379c..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_reassembly.c +++ /dev/null @@ -1,134 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_reassembly.c - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - ***************************************************************************/ -#define RLC_AM_C -#include "rtos_header.h" -#include "platform_types.h" -//----------------------------------------------------------------------------- -#include "rlc.h" -#include "rlc_am_entity.h" -#include "rlc_am_structs.h" -#include "rlc_primitives.h" -#include "rlc_am_constants.h" -#include "list.h" -#include "LAYER2/MAC/extern.h" -#define DEBUG_RLC_AM_SEND_SDU -//#define DEBUG_REASSEMBLY -//#define DEBUG_RLC_AM_DISPLAY_ASCII_DATA - -//----------------------------------------------------------------------------- -void -reassembly (uint8_t* srcP, uint16_t lengthP, struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - int sdu_max_size_allowed; -#ifdef DEBUG_RLC_AM_DISPLAY_ASCII_DATA - int index; -#endif -#ifdef DEBUG_REASSEMBLY - msg ("[RLC_AM][RB %d][REASSEMBLY] reassembly() %d bytes\n", rlcP->rb_id, lengthP); -#endif - - if ((rlcP->data_plane)) { - sdu_max_size_allowed = RLC_SDU_MAX_SIZE_DATA_PLANE; - - } else { - sdu_max_size_allowed = RLC_SDU_MAX_SIZE_CONTROL_PLANE; - } - - if (rlcP->output_sdu_in_construction == NULL) { - rlcP->output_sdu_in_construction = get_free_mem_block (sdu_max_size_allowed); - rlcP->output_sdu_size_to_write = 0; - } - -#ifdef DEBUG_REASSEMBLY - msg ("[RLC_AM][RB %d][REASSEMBLY] reassembly() %d bytes sdu_max_size allowed %d\n", rlcP->rb_id, lengthP, sdu_max_size_allowed); -#endif - - if ((rlcP->output_sdu_in_construction)) { -#ifdef DEBUG_RLC_AM_DISPLAY_ASCII_DATA - msg ("[RLC_AM][RB %d][REASSEMBLY] DATA :", rlcP->rb_id); - - for (index = 0; index < lengthP; index++) { - //msg ("%c", srcP[index]); - msg ("%02X.", srcP[index]); - } - - msg ("\n"); -#endif - - // OOOPS - if ((lengthP + rlcP->output_sdu_size_to_write) <= sdu_max_size_allowed) { - memcpy (&rlcP->output_sdu_in_construction->data[rlcP->output_sdu_size_to_write], srcP, lengthP); - rlcP->output_sdu_size_to_write += lengthP; - - } else { - rlcP->output_sdu_size_to_write = 0; -#ifdef DEBUG_REASSEMBLY - msg ("[RLC_AM %p][REASSEMBLY] ERROR SDU IN CONSTRUCTION TOO BIG %d Bytes MAX SIZE ALLOWED %d\n", rlcP, lengthP + rlcP->output_sdu_size_to_write, - sdu_max_size_allowed); -#endif - } - } - -#ifdef DEBUG_REASSEMBLY - - else { - msg ("[RLC_AM %p][REASSEMBLY] ERROR OUTPUT SDU IS NULL\n", rlcP); - } - -#endif -} - -//----------------------------------------------------------------------------- -void -send_sdu (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - if ((rlcP->output_sdu_in_construction) && (rlcP->output_sdu_size_to_write)) { -#ifdef DEBUG_RLC_AM_SEND_SDU - msg ("[RLC_AM][RB %d][SEND_SDU] send_SDU() %d bytes\n", rlcP->rb_id, rlcP->output_sdu_size_to_write); -#endif -#ifdef BENCH_QOS_L2 - fprintf (bench_l2, "[SDU DELIVERY] FRAME %d SIZE %d RB %d RLC-AM %p\n", Mac_rlc_xface->frame, rlcP->output_sdu_size_to_write, rlcP->rb_id, rlcP); -#endif - rlc_data_ind (rlcP->module_id, rlcP->rb_id, rlcP->output_sdu_size_to_write, rlcP->output_sdu_in_construction, rlcP->data_plane); - rlcP->output_sdu_in_construction = NULL; - rlcP->output_sdu_size_to_write = 0; - rlcP->stat_rx_sdu += 1; - } -} diff --git a/openair2/LAYER2/RLC/AM/rlc_am_reassembly_proto_extern.h b/openair2/LAYER2/RLC/AM/rlc_am_reassembly_proto_extern.h deleted file mode 100755 index 33f5e0a95502f1fab054027b45772150ebdd75a0..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_reassembly_proto_extern.h +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_reassembly_proto_extern.h - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - ***************************************************************************/ -# ifndef __RLC_AM_REASSEMBLY_PROTO_EXTERN_H__ -# define __RLC_AM_REASSEMBLY_PROTO_EXTERN_H__ -//----------------------------------------------------------------------------- -# include "rlc_am_entity.h" -//----------------------------------------------------------------------------- -extern void reassembly (uint8_t * srcP, uint16_t lengthP, struct rlc_am_entity *rlcP); -extern void send_sdu (struct rlc_am_entity *rlcP); -# endif diff --git a/openair2/LAYER2/RLC/AM/rlc_am_receiver.c b/openair2/LAYER2/RLC/AM/rlc_am_receiver.c deleted file mode 100755 index fcbd565c8a609742aa2ab3b5d2f8b320522d436a..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_receiver.c +++ /dev/null @@ -1,626 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_receiver.c - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - ***************************************************************************/ -#include "rtos_header.h" -#include "platform_types.h" -//----------------------------------------------------------------------------- -#include "rlc_am_entity.h" -#include "rlc_def.h" -#include "rlc_am_structs.h" -#include "rlc_am_constants.h" -#include "rlc_am_reassembly_proto_extern.h" -#include "rlc_am_proto_extern.h" -#include "rlc_am_util_proto_extern.h" -#include "mem_block.h" - -//#define DEBUG_RECEIVER_BUFFER -//#define DEBUG_REASSEMBLY -//#define DEBUG_STATUS -//----------------------------------------------------------------------------- -void receiver_retransmission_management (struct rlc_am_entity* rlcP, mem_block_t* pduP, struct rlc_am_pdu_header* rlc_headerP); -void free_receiver_buffer (struct rlc_am_entity* rlcP, uint16_t indexP); -void insert_into_receiver_buffer (struct rlc_am_entity* rlcP, uint16_t indexP, mem_block_t* pduP); -void process_receiver_buffer_15 (struct rlc_am_entity* rlcP); -void process_receiver_buffer_7 (struct rlc_am_entity* rlcP); -//----------------------------------------------------------------------------- -void -receiver_retransmission_management (struct rlc_am_entity* rlcP, mem_block_t* pduP, struct rlc_am_pdu_header* rlc_headerP) -{ - //----------------------------------------------------------------------------- - uint16_t id; - uint16_t id_index; - /* From TS25.3222 V5.0.0 - Upon reception of an AMD PDU, the Receiver shall: - - update VR(R), VR(H) and VR(MR) state variables for each received AMD PDU (see clause 9.4); - - if a received AMD PDU includes a "Polling bit" set to "1", or "Missing PDU Indicator" is configured and the - Receiver detects that a PDU is missing: - - initiate the STATUS PDU transfer procedure; - - reassemble the received AMD PDUs into RLC SDUs; - - if "In-Sequence Delivery" is configured: - - deliver the RLC SDUs in-sequence (i.e. in the same order as the RLC SDUs were originally transmitted by - the peer entity) to upper layers through the AM-SAP. - - otherwise: (NOT IMPLEMENTED) - - deliver the RLC SDUs in arbitrary order to upper layers through the AM-SAP. */ -#ifdef DEBUG_RECEIVER_BUFFER - msg("[RLC_AM][DEBUG] receiver_retransmission_management() received PDU %p\n", pduP); - display_protocol_vars_rlc_am(rlcP); -#endif - id = (((uint16_t) (rlc_headerP->byte1 & RLC_AM_SN_1ST_PART_MASK)) << 5) | ((rlc_headerP->byte2 & RLC_AM_SN_2ND_PART_MASK) >> 3); - // general case - ((struct rlc_am_rx_pdu_management*) (pduP->data))->sn = id; - id_index = id % rlcP->recomputed_configured_rx_window_size; -#ifdef DEBUG_RECEIVER_BUFFER - msg("[RLC][RB %d][DEBUG] receiver_retransmission_management() received PDU %04X :\n", rlcP->rb_id, id); - //display_protocol_vars_rlc_am(rlcP); -#endif - - // test poll bit for status pdu transmission; - if ((rlc_headerP->byte2 & RLC_AM_P_STATUS_REPORT_MASK) == RLC_AM_P_STATUS_REPORT_REQUESTED) { - rlcP->send_status_pdu_requested = 1; -#ifdef DEBUG_STATUS - msg ("[RLC_AM][RB %d][RECEIVER_BUFFER] STATUS REQUESTED BY PEER\n", rlcP->rb_id); -#endif - } - - if (id == rlcP->vr_r) { -#ifdef DEBUG_RECEIVER_BUFFER - msg ("[RLC_AM][RB %d][RECEIVER_BUFFER] RECEIVED %p VR(R)=0x%04X id_index=0x%02X VR(H)=0x%04X\n", rlcP->rb_id, pduP, rlcP->vr_r, id_index, rlcP->vr_h); -#endif - insert_into_receiver_buffer (rlcP, id_index, pduP); - - // update vr_h; - if (rlcP->vr_h == id) { - rlcP->vr_h = (id + 1) & SN_12BITS_MASK; - } - - adjust_vr_r_mr (rlcP); - - } else { - rlcP->send_status_pdu_requested = 1; -#ifdef DEBUG_RECEIVER_BUFFER - msg ("[RLC_AM][RB %d][RECEIVER_BUFFER] RECEIVED %p sn=0x%04X id_index=0x%02X VR(R)=0x%04X VR(H)=0x%04X WILL SEND STATUS\n", rlcP->rb_id, pduP, id, id_index, - rlcP->vr_r, rlcP->vr_h); -#endif - - //------------------------------------; - // CASE VR(R)<VR(H)<VR(MR); - //------------------------------------; - if ((rlcP->vr_r <= rlcP->vr_h) && (rlcP->vr_h <= rlcP->vr_mr) && (id < rlcP->vr_mr) && (id > rlcP->vr_r)) { -#ifdef DEBUG_RECEIVER_BUFFER - msg ("[RLC_AM][RB %d][RECEIVER_BUFFER] RECEIVED %p sn 0x%04X IN WINDOW\n", rlcP->rb_id, pduP, id); -#endif - insert_into_receiver_buffer (rlcP, id_index, pduP); - - // CASE VR(R)<VR(H)<id<VR(MR); - if (id >= rlcP->vr_h) { - rlcP->vr_h = (id + 1) & SN_12BITS_MASK; - } - - //------------------------------------; - // CASE id<VR(MR)<VR(R)<VR(H); - //------------------------------------; - // CASE VR(MR)<VR(R)<VR(H)<id; - - } else if (((rlcP->vr_mr < rlcP->vr_r) && (rlcP->vr_h >= rlcP->vr_r) && (id < rlcP->vr_mr)) || ((rlcP->vr_mr < rlcP->vr_r) && (rlcP->vr_h >= rlcP->vr_r) - && (id > rlcP->vr_r))) { -#ifdef DEBUG_RECEIVER_BUFFER - msg ("[RLC_AM][RB %d][RECEIVER_BUFFER] RECEIVED %p sn 0x%04X IN REVERSED WINDOW\n", rlcP->rb_id, pduP, id); -#endif - insert_into_receiver_buffer (rlcP, id_index, pduP); - - if ((id >= rlcP->vr_h) || (id < rlcP->vr_mr)) { - rlcP->vr_h = (id + 1) & SN_12BITS_MASK; - } - - //------------------------------------; - // CASE VR(H)<VR(MR)<VR(R); - //------------------------------------; - - } else if ((rlcP->vr_h <= rlcP->vr_mr) && (rlcP->vr_mr < rlcP->vr_r)) { - if (id < rlcP->vr_mr) { -#ifdef DEBUG_RECEIVER_BUFFER - msg ("[RLC_AM][RB %d][RECEIVER_BUFFER] RECEIVED %p sn 0x%04X IN REVERSED WINDOW\n", rlcP->rb_id, pduP, id); -#endif - insert_into_receiver_buffer (rlcP, id_index, pduP); - - if (id >= rlcP->vr_h) { - rlcP->vr_h = (id + 1) & SN_12BITS_MASK; - } - - } else if (id > rlcP->vr_r) { -#ifdef DEBUG_RECEIVER_BUFFER - msg ("[RLC_AM][RB %d][RECEIVER_BUFFER] RECEIVED %p sn 0x%04X IN REVERSED WINDOW\n", rlcP->rb_id, pduP, id); -#endif - insert_into_receiver_buffer (rlcP, id_index, pduP); - - } else { - // discard this PDU; -#ifdef DEBUG_RECEIVER_BUFFER - msg ("[RLC_AM][RB %d][RECEIVER_BUFFER] RECEIVED %p sn 0x%04X OUT OF WINDOW\n", rlcP->rb_id, pduP, id); -#endif - rlcP->stat_rx_data_pdu_out_of_window += 1; - free_mem_block (pduP); - } - - //------------------------------------; - // REJECT; - //------------------------------------; - - } else { - // discard this PDU; -#ifdef DEBUG_RECEIVER_BUFFER - msg ("[RLC_AM][RB %d][RECEIVER_BUFFER] RECEIVED %p sn 0x%04X OUT OF WINDOW\n", rlcP->rb_id, pduP, id); -#endif - rlcP->stat_rx_data_pdu_out_of_window += 1; - free_mem_block (pduP); - } - } -} - -//----------------------------------------------------------------------------- -void -free_receiver_buffer (struct rlc_am_entity* rlcP, uint16_t indexP) -{ - //----------------------------------------------------------------------------- - if (indexP < rlcP->recomputed_configured_rx_window_size) { - if (rlcP->receiver_buffer[indexP]) { -#ifdef DEBUG_FREE_RECEIVER_BUFFER - msg ("[RLC_AM][RB %d][RECEIVER_BUFFER] FREE PDU %p index 0x%4X\n", rlcP->rb_id, rlcP->receiver_buffer[indexP], indexP); -#endif - free_mem_block (rlcP->receiver_buffer[indexP]); - rlcP->receiver_buffer[indexP] = NULL; - } - - return; - } - - msg ("[RLC_AM][RB %d][RECEIVER_BUFFER] ERROR free_receiver_buffer() invalid index in array 0x%2X\n", rlcP->rb_id, indexP); -} - -//----------------------------------------------------------------------------- -void -insert_into_receiver_buffer (struct rlc_am_entity* rlcP, uint16_t indexP, mem_block_t* pduP) -{ - //----------------------------------------------------------------------------- - if (pduP) { - if (indexP < rlcP->recomputed_configured_rx_window_size) { -#ifdef DEBUG_RECEIVER_BUFFER - - if (rlcP->receiver_buffer[indexP] != NULL) { - msg ("[RLC_AM][RB %d][RECEIVER_BUFFER] ERROR insert_into_receiver_buffer() location is not NULL, index in array = 0x%2X\n", rlcP->rb_id, indexP); - display_protocol_vars_rlc_am (rlcP); - } - -#endif - - // last received is good - if (rlcP->receiver_buffer[indexP] != NULL) { - free_mem_block (rlcP->receiver_buffer[indexP]); - } - - rlcP->receiver_buffer[indexP] = pduP; - return; - } - - msg ("[RLC_AM][RB %d][RECEIVER_BUFFER] ERROR insert_into_receiver_buffer() invalid index in array 0x%2X\n", rlcP->rb_id, indexP); - return; - } - - msg ("[RLC_AM][RB %d][RECEIVER_BUFFER] ERROR insert_into_receiver_buffer() pdu is NULL index 0x%2X\n", rlcP->rb_id, indexP); -} - -//----------------------------------------------------------------------------- -void -process_receiver_buffer_15 (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - struct rlc_am_pdu_header* rlc_header; - mem_block_t* pdu; - uint16_t vr_r; - uint16_t working_sn; - uint16_t working_sn_index; // index in buffer - uint8_t* data_pdu; - uint16_t li[RLC_AM_SEGMENT_NB_MAX_LI_PER_PDU]; - uint16_t remaining_data_size; - uint8_t nb_li; - uint8_t li_index; - uint8_t li_start_index; - uint8_t reassembly_after_discard; - // should start reassembly with sn working_sn - working_sn = (rlcP->last_reassemblied_sn + 1) & SN_12BITS_MASK; - working_sn_index = working_sn % rlcP->recomputed_configured_rx_window_size; - vr_r = rlcP->vr_r; - reassembly_after_discard = 0; - - while (rlcP->receiver_buffer[working_sn_index]) { - pdu = rlcP->receiver_buffer[working_sn_index]; - nb_li = 0; - li_index = 0; - rlc_header = (struct rlc_am_pdu_header*) (((struct rlc_am_rx_pdu_management*) (pdu->data))->first_byte); - - if ((rlcP->discard_reassembly_start_sn == ((struct rlc_am_rx_pdu_management*) (pdu->data))->sn)) { - rlcP->output_sdu_size_to_write = 0; - reassembly_after_discard = 1; // keep trace of entering in this block - - if (!(rlc_header->byte2 & RLC_HE_MASK) == RLC_HE_SUCC_BYTE_CONTAINS_DATA) { - while ((li[nb_li] = ((((uint16_t) rlc_header->li_data_7[nb_li << 1]) << 8) + rlc_header->li_data_7[(nb_li << 1) + 1])) & RLC_E_NEXT_FIELD_IS_LI_E) { - li[nb_li] = li[nb_li] & (~(uint16_t) RLC_E_NEXT_FIELD_IS_LI_E); - nb_li++; - } - - nb_li++; // count the first li - } - - // this variable may be changed by the reception of a mrw sufi - //li_start_index = rlcP->discard_reassembly_after_li + 1; // reassembly will start at this index - li_start_index = rlcP->discard_reassembly_after_li; // reassembly will start at this index - // after reception of sufi mrw the starting index for li will be 0 - rlcP->discard_reassembly_after_li = RLC_AM_DISCARD_REASSEMBLY_AT_LI_INDEX_0; // =-1 - remaining_data_size = rlcP->pdu_size - 2 - (nb_li << 1); - data_pdu = (uint8_t*) (&rlc_header->li_data_7[nb_li << 1]); - - while (li_index < nb_li) { - switch (li[li_index]) { - case RLC_LI_LAST_PDU_EXACTLY_FILLED: - if (li_index >= li_start_index) { - send_sdu (rlcP); - } - - break; - - case RLC_LI_LAST_PDU_ONE_BYTE_SHORT: - if (li_index >= li_start_index) { - rlcP->output_sdu_size_to_write -= 1; - send_sdu (rlcP); - } - - break; - - case RLC_LI_PDU_PIGGY_BACKED_STATUS: // ignore - case RLC_LI_PDU_PADDING: - remaining_data_size = 0; - break; - - default: // li is length - remaining_data_size = remaining_data_size - (li[li_index] >> 1); - - if (li_index >= li_start_index) { - reassembly (data_pdu, (li[li_index] >> 1), rlcP); - send_sdu (rlcP); - } - - data_pdu = (uint8_t*) ((uint32_t) data_pdu + (li[li_index] >> 1)); - } - - li_index++; - } - - if ((remaining_data_size)) { - reassembly (data_pdu, remaining_data_size, rlcP); - remaining_data_size = 0; - } - - free_receiver_buffer (rlcP, working_sn_index); - rlcP->discard_reassembly_start_sn = RLC_AM_SN_INVALID; - rlcP->last_reassemblied_sn = working_sn; - working_sn = (rlcP->last_reassemblied_sn + 1) & SN_12BITS_MASK; - working_sn_index = working_sn % rlcP->recomputed_configured_rx_window_size; - - // patch to make the protocol working - // return 1 if sn1 > sn2 - // return 0 if sn1 = sn2 - // return -1 if sn1 < sn2 - if (rlc_am_comp_sn (rlcP, rlcP->vr_r, rlcP->vr_r, working_sn) < 0) { - rlcP->vr_r = working_sn; - rlcP->vr_mr = (rlcP->vr_r + rlcP->configured_rx_window_size - 1) & SN_12BITS_MASK; - } - - } else { - // exploit HE field info - if ((rlc_header->byte2 & RLC_HE_MASK) == RLC_HE_SUCC_BYTE_CONTAINS_DATA) { - reassembly ((uint8_t*) (rlc_header->li_data_7), rlcP->pdu_size - 2, rlcP); - - } else { - while ((li[nb_li] = ((((uint16_t) rlc_header->li_data_7[nb_li << 1]) << 8) + rlc_header->li_data_7[(nb_li << 1) + 1])) & RLC_E_NEXT_FIELD_IS_LI_E) { - //while ((li[nb_li] = (rlc_header->li.li_data_15[nb_li].optional)) & RLC_E_NEXT_FIELD_IS_LI_E) { - li[nb_li] = li[nb_li] & (~(uint16_t) RLC_E_NEXT_FIELD_IS_LI_E); - nb_li++; - } - - nb_li++; - remaining_data_size = rlcP->pdu_size - 2 - (nb_li << 1); - data_pdu = (uint8_t*) (&rlc_header->li_data_7[nb_li << 1]); - - while (li_index < nb_li) { - switch (li[li_index]) { - case RLC_LI_LAST_PDU_EXACTLY_FILLED: - send_sdu (rlcP); - break; - - case RLC_LI_LAST_PDU_ONE_BYTE_SHORT: - rlcP->output_sdu_size_to_write -= 1; - send_sdu (rlcP); - break; - - case RLC_LI_PDU_PIGGY_BACKED_STATUS: // ignore - case RLC_LI_PDU_PADDING: - remaining_data_size = 0; - break; - - default: // li is length - remaining_data_size = remaining_data_size - (li[li_index] >> 1); - reassembly (data_pdu, (li[li_index] >> 1), rlcP); - data_pdu = (uint8_t*) ((uint32_t) data_pdu + (li[li_index] >> 1)); - send_sdu (rlcP); - } - - li_index++; - } - - if ((remaining_data_size)) { - reassembly (data_pdu, remaining_data_size, rlcP); - remaining_data_size = 0; - } - } - - free_receiver_buffer (rlcP, working_sn_index); - rlcP->last_reassemblied_sn = working_sn; - working_sn = (rlcP->last_reassemblied_sn + 1) & SN_12BITS_MASK; - working_sn_index = working_sn % rlcP->recomputed_configured_rx_window_size; - - if ((reassembly_after_discard)) { - // return 1 if vr_r > working_sn - // return 0 if vr_r = working_sn - // return -1 if vr_r < working_sn - if (rlc_am_comp_sn (rlcP, rlcP->vr_r, rlcP->vr_r, working_sn) < 0) { - rlcP->vr_r = working_sn; -#ifdef DEBUG_REASSEMBLY - msg ("[RLC_AM][RB %d][REASSEMBLY] DETECTED PDU AFTER DISCARD ADJUST VR(R) 0x%04X\n", rlcP->rb_id, rlcP->vr_r); -#endif - rlcP->vr_mr = (rlcP->vr_r + rlcP->configured_rx_window_size - 1) & SN_12BITS_MASK; - } - } - } - } -} - -//----------------------------------------------------------------------------- -void -process_receiver_buffer_7 (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - struct rlc_am_pdu_header* rlc_header; - mem_block_t* pdu; - uint16_t vr_r; - uint16_t working_sn; - uint16_t working_sn_index; // index in buffer - uint8_t* data_pdu; - uint8_t li[RLC_AM_SEGMENT_NB_MAX_LI_PER_PDU]; - uint16_t remaining_data_size; - int8_t nb_li; - int8_t li_index; - int8_t li_start_index; - uint8_t reassembly_after_discard; - uint8_t sdu_sent=0; - // should start reassembly with sn working_sn - working_sn = (rlcP->last_reassemblied_sn + 1) & SN_12BITS_MASK; - working_sn_index = working_sn % rlcP->recomputed_configured_rx_window_size; - vr_r = rlcP->vr_r; - reassembly_after_discard = 0; - - while (rlcP->receiver_buffer[working_sn_index]) { - pdu = rlcP->receiver_buffer[working_sn_index]; - nb_li = 0; - li_index = 0; - rlc_header = (struct rlc_am_pdu_header*) (((struct rlc_am_rx_pdu_management*) (pdu->data))->first_byte); -#ifdef DEBUG_REASSEMBLY - msg ("[RLC_AM][RB %d][REASSEMBLY] PDU %p SN 0x%04X (sdu_sent %d)\n", rlcP->rb_id, pdu, working_sn,sdu_sent); -#endif - - if ((rlcP->discard_reassembly_start_sn == ((struct rlc_am_rx_pdu_management*) (pdu->data))->sn)) { - rlcP->output_sdu_size_to_write = 0; - reassembly_after_discard = 1; // keep trace of entering in this block - - if (!(rlc_header->byte2 & RLC_HE_MASK) == RLC_HE_SUCC_BYTE_CONTAINS_DATA) { - while ((li[nb_li] = (rlc_header->li_data_7[nb_li])) & RLC_E_NEXT_FIELD_IS_LI_E) { - li[nb_li] = li[nb_li] & (~(uint8_t) RLC_E_NEXT_FIELD_IS_LI_E); - nb_li++; - } - - nb_li++; // count the first li - } - -#ifdef DEBUG_REASSEMBLY - msg ("[RLC_AM][RB %d][REASSEMBLY] DETECTED PDU TO BE REASSEMBLIED AFTER DISCARD, START SN 0x%04X hex VR(R) 0x%04X\n", rlcP->rb_id, - rlcP->discard_reassembly_start_sn, rlcP->vr_r); -#endif - // this variable may be changed by the reception of a mrw sufi - //li_start_index = rlcP->discard_reassembly_after_li + 1; // reassembly will start at this index - li_start_index = rlcP->discard_reassembly_after_li; // reassembly will start at this index - // after reception of sufi mrw the starting index for li will be 0 - rlcP->discard_reassembly_after_li = RLC_AM_DISCARD_REASSEMBLY_AT_LI_INDEX_0; // =-1 - remaining_data_size = rlcP->pdu_size - 2 - (nb_li); - data_pdu = (uint8_t*) (&rlc_header->li_data_7[nb_li]); - - while (li_index < nb_li) { - switch (li[li_index]) { - case (uint8_t) RLC_LI_LAST_PDU_EXACTLY_FILLED: -#ifdef DEBUG_REASSEMBLY - msg ("[RLC_AM][RB %d][REASSEMBLY] PDU SN 0x%04X GET LI RLC_LI_LAST_PDU_EXACTLY_FILLED REMAINING DATA SIZE %d, li_index %d, li_start_index %d\n", rlcP->rb_id, - working_sn, remaining_data_size, li_index, li_start_index); -#endif - - if (li_index >= li_start_index) { - send_sdu (rlcP); - sdu_sent=1; - } - - break; - - case (uint8_t) RLC_LI_PDU_PIGGY_BACKED_STATUS: // ignore - case (uint8_t) RLC_LI_PDU_PADDING: -#ifdef DEBUG_REASSEMBLY - msg ("[RLC_AM][RB %d][REASSEMBLY] PDU SN 0x%04X GET LI RLC_LI_PDU_PADDING\n", rlcP->rb_id, working_sn); -#endif - remaining_data_size = 0; - break; - - default: // li is length -#ifdef DEBUG_REASSEMBLY - msg ("[RLC_AM][RB %d][REASSEMBLY] PDU SN 0x%04X GET LI SIZE %d\n", rlcP->rb_id, working_sn, li[li_index] >> 1); -#endif - remaining_data_size = remaining_data_size - (li[li_index] >> 1); - - if (li_index >= li_start_index) { - reassembly (data_pdu, (li[li_index] >> 1), rlcP); - send_sdu (rlcP); - sdu_sent=1; - } - - data_pdu = (uint8_t*) ((uint32_t) data_pdu + (li[li_index] >> 1)); - } - - li_index++; - } - - if ((remaining_data_size)) { - reassembly (data_pdu, remaining_data_size, rlcP); - remaining_data_size = 0; - } - - free_receiver_buffer (rlcP, working_sn_index); - rlcP->discard_reassembly_start_sn = RLC_AM_SN_INVALID; - rlcP->last_reassemblied_sn = working_sn; - working_sn = (rlcP->last_reassemblied_sn + 1) & SN_12BITS_MASK; - working_sn_index = working_sn % rlcP->recomputed_configured_rx_window_size; - - // return 1 if vr_r > working_sn - // return 0 if vr_r = working_sn - // return -1 if vr_r < working_sn - if (rlc_am_comp_sn (rlcP, rlcP->vr_r, rlcP->vr_r, working_sn) < 0) { - rlcP->vr_r = working_sn; -#ifdef DEBUG_REASSEMBLY - msg ("[RLC_AM][RB %d][REASSEMBLY] DETECTED PDU AFTER DISCARD ADJUST VR(R) 0x%04X hex\n", rlcP->rb_id, rlcP->vr_r); -#endif - rlcP->vr_mr = (rlcP->vr_r + rlcP->configured_rx_window_size - 1) & SN_12BITS_MASK; - } - - } else { -#ifdef DEBUG_REASSEMBLY - msg("[RLC][AM] Reassembly, No discard. rlc_header->byte2 %d\n"); -#endif - - // exploit HE field info - if ((rlc_header->byte2 & RLC_HE_MASK) == RLC_HE_SUCC_BYTE_CONTAINS_DATA) { - msg("WILL REASSEMBLY INDEX %04X\n", working_sn_index); - reassembly ((uint8_t*) (rlc_header->li_data_7), rlcP->pdu_size - 2, rlcP); - - } else { - while ((li[nb_li] = (rlc_header->li_data_7[nb_li])) & RLC_E_NEXT_FIELD_IS_LI_E) { - li[nb_li] = li[nb_li] & (~(uint8_t) RLC_E_NEXT_FIELD_IS_LI_E); - nb_li++; - } - - nb_li++; - remaining_data_size = rlcP->pdu_size - 2 - nb_li; - data_pdu = (uint8_t*) (&rlc_header->li_data_7[nb_li]); - - while (li_index < nb_li) { - switch (li[li_index]) { - case (uint8_t) RLC_LI_LAST_PDU_EXACTLY_FILLED: -#ifdef DEBUG_REASSEMBLY - msg ("[RLC_AM][RB %d][REASSEMBLY] PDU SN 0x%04X GET LI RLC_LI_LAST_PDU_EXACTLY_FILLED NUM LI %d\n", rlcP->rb_id, working_sn,nb_li); -#endif - send_sdu (rlcP); - sdu_sent=1; - break; - - case (uint8_t) RLC_LI_PDU_PIGGY_BACKED_STATUS: // ignore - case (uint8_t) RLC_LI_PDU_PADDING: -#ifdef DEBUG_REASSEMBLY - msg ("[RLC_AM][RB %d][REASSEMBLY] PDU SN 0x%04X GET LI RLC_LI_PDU_PADDING\n", rlcP->rb_id, working_sn); -#endif - remaining_data_size = 0; - break; - - default: // li is length -#ifdef DEBUG_REASSEMBLY - msg ("[RLC_AM][RB %d][REASSEMBLY] PDU SN 0x%04X GET LI SIZE %d Bytes\n", rlcP->rb_id, working_sn, li[li_index] >> 1); -#endif - remaining_data_size = remaining_data_size - (li[li_index] >> 1); - reassembly (data_pdu, (li[li_index] >> 1), rlcP); - data_pdu = (uint8_t*) ((uint32_t) data_pdu + (li[li_index] >> 1)); - send_sdu (rlcP); - sdu_sent=1; - } - - li_index++; - } - - if ((remaining_data_size)) { - //msg("WILL REASSEMBLY INDEX %04X\n", working_sn_index); - reassembly (data_pdu, remaining_data_size, rlcP); - remaining_data_size = 0; - } - } - - free_receiver_buffer (rlcP, working_sn_index); - rlcP->last_reassemblied_sn = working_sn; - working_sn = (rlcP->last_reassemblied_sn + 1) & SN_12BITS_MASK; - working_sn_index = working_sn % rlcP->recomputed_configured_rx_window_size; - - if ((reassembly_after_discard)) { - // return 1 if vr_r > working_sn - // return 0 if vr_r = working_sn - // return -1 if vr_r < working_sn - if (rlc_am_comp_sn (rlcP, rlcP->vr_r, rlcP->vr_r, working_sn) < 0) { - rlcP->vr_r = working_sn; -#ifdef DEBUG_REASSEMBLY - msg ("[RLC_AM][RB %d][REASSEMBLY] DETECTED PDU AFTER DISCARD ADJUST VR(R) 0x%04X\n", rlcP->rb_id, rlcP->vr_r); -#endif - rlcP->vr_mr = (rlcP->vr_r + rlcP->configured_rx_window_size - 1) & SN_12BITS_MASK; - } - } - } - - msg("receiver_buffer[%d] %p (sdu_sent %d)\n",working_sn_index,rlcP->receiver_buffer[working_sn_index],sdu_sent); - } - - // if (sdu_sent == 0) { - // msg("[RLC_AM][RB %d][REASSEMBLY] Forcing send_sdu (sent_sdu == 0)\n",rlcP->rb_id); - // send_sdu(rlcP); - // } -} diff --git a/openair2/LAYER2/RLC/AM/rlc_am_receiver_proto_extern.h b/openair2/LAYER2/RLC/AM/rlc_am_receiver_proto_extern.h deleted file mode 100755 index 0b635851932e7860cae99c27b802d6989523e6b8..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_receiver_proto_extern.h +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_receiver_proto_extern.h - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - ***************************************************************************/ -# ifndef __RLC_AM_RECEIVER_PROTO_EXTERN_H__ -# define __RLC_AM_RECEIVER_PROTO_EXTERN_H__ -//----------------------------------------------------------------------------- -# include "rlc_am_entity.h" -# include "rlc_am_structs.h" -# include "mem_block.h" -//----------------------------------------------------------------------------- -extern void receiver_retransmission_management (struct rlc_am_entity *rlcP, mem_block_t * pduP, struct rlc_am_pdu_header *rlc_headerP); -extern void free_receiver_buffer (struct rlc_am_entity *rlcP, uint16_t indexP); -extern void insert_into_receiver_buffer (struct rlc_am_entity *rlcP, uint16_t indexP, mem_block_t * pduP); -extern void process_receiver_buffer_15 (struct rlc_am_entity *rlcP); -extern void process_receiver_buffer_7 (struct rlc_am_entity *rlcP); -# endif diff --git a/openair2/LAYER2/RLC/AM/rlc_am_reset.c b/openair2/LAYER2/RLC/AM/rlc_am_reset.c deleted file mode 100755 index 06366671c5e5558e8e09bbed24bcac357f07a443..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_reset.c +++ /dev/null @@ -1,402 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_reset.c - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - ***************************************************************************/ -/* From 3GPP TS 25.322 V5.0.0 (2002-03) -The RLC reset procedure is used to reset two RLC peer entities, which are operating in acknowledged mode. -During the reset procedure the hyper frame numbers (HFN) in UTRAN and UE are synchronised. Two HFNs -used for ciphering needs to be synchronised, DL HFN in downlink and UL HFN in uplink. - In the reset procedure, the highest UL HFN and DL HFN used by the RLC -entity in the transmitting sides, i.e. the HFNs associated with AMD PDUs of "Sequence Number"=VT(S)-1 if at least -one AMD PDU had been transmitted or of "Sequence Number"=0 if no AMD PDU had been transmitted, are -exchanged between UE and UTRAN. -The RESET PDUs and the RESET ACK PDUs have higher priority than AMD PDUs. -*/ -#define RLC_AM_C -#include "rtos_header.h" -#include "platform_types.h" -//----------------------------------------------------------------------------- -#include "rlc.h" -#include "rlc_am_entity.h" -#include "rlc_am_structs.h" -#include "rlc_am_constants.h" -#include "rlc_am_control_primitives_proto_extern.h" -#include "rlc_am_fsm_proto_extern.h" -#include "list.h" -#include "mem_block.h" -#include "umts_timer_proto_extern.h" -#include "LAYER2/MAC/extern.h" -#define DEBUG_RESET -//----------------------------------------------------------------------------- -void send_reset_ack_pdu (uint8_t rsnP, struct rlc_am_entity* rlcP); -void send_reset_pdu (struct rlc_am_entity* rlcP); -void reset_rlc_am (struct rlc_am_entity* rlcP); -void process_reset_ack (mem_block_t* pduP, struct rlc_am_reset_header* controlP, struct rlc_am_entity* rlcP); -void process_reset (mem_block_t* pduP, struct rlc_am_reset_header* controlP, struct rlc_am_entity* rlcP); -//----------------------------------------------------------------------------- -void -rlc_am_reset_time_out (struct rlc_am_entity* rlcP, mem_block_t* not_usedP) -{ - //----------------------------------------------------------------------------- - /* from 3GPP TS 25.322 V5.0.0 (2002-03) - If Timer_RST expires before the reset procedure is terminated, the Sender shall: - - if VT(RST)<MaxRST-1: - - set the RESET PDU as previously transmitted (even if additional SDUs were discarded in the mean-time); - - transmit RESET PDU; - - increment VT(RST) by one; - - restart Timer_RST. - Unrecoverable error (VT(RST) MaxRST) - The Sender shall: - - if VT(RST) becomes larger than or equal to MaxRST: - - indicate unrecoverable error to upper layer. - */ - rlcP->timer_rst = NULL; -#ifdef DEBUG_RESET - msg ("\n******************************************************************\n"); - msg ("[RLC_AM][RB %d] RESET TIME OUT VT(RST) = %d frame %d\n", rlcP->rb_id, rlcP->vt_rst, Mac_rlc_xface->frame); - msg ("\n******************************************************************\n"); -#endif - - if (rlcP->protocol_state & RLC_RESET_PENDING_STATE) { - if (rlcP->vt_rst < rlcP->max_rst - 1) { - send_reset_pdu (rlcP); - rlcP->vt_rst += 1; - - } else { - //rrc_indication_unrecoverable_error_from_rlc_am(rlcP); - // notification not raised to RRC, continue. (TO DO) - msg ("\n******************************************************************\n"); - msg ("[RLC_AM][RB %d] RESET TIME OUT VT(RST) >= max_rst frame %d REPORT TO RRC\n", rlcP->rb_id, Mac_rlc_xface->frame); - msg ("\n******************************************************************\n"); - send_reset_pdu (rlcP); - rlcP->vt_rst += 1; - rlc_data_conf (0, rlcP->rb_id, 0,RLC_TX_CONFIRM_FAILURE, rlcP->data_plane); // mui, rb_ib, status -#ifdef NODE_MT -#warning rrc_ue_CPHY_Out_Synch_rx should be called - //rrc_ue_CPHY_Out_Synch_rx (1); // Temporary hack to disconnect mobile upon RLC AM timeout -#endif /* NODE_MT */ - } - } -} - -//----------------------------------------------------------------------------- -void -send_reset_pdu (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - mem_block_t* pdu; - struct rlc_am_reset_header* header; - - /* From TS 25.322 V5.0.0 (2002-03) - RESET PDU contents to set - The Sender shall: - - set the HFNI field to the currently highest used HFN (DL HFN when the RESET PDU is sent by UTRAN or UL - HFN when the RESET PDU is sent by the UE); - - set the RSN field to the sequence number of the RESET PDU. The sequence number of the first RESET PDU - after the AM entity is established or re-established shall be "0". This sequence number is incremented every time - a new RESET PDU is transmitted, but not when a RESET PDU is retransmitted. - */ - if (!(rlcP->timer_rst)) { - if (rlcP->vt_rst == 0) { // first transmission of reset PDU - rlcP->reset_sequence_number ^= 1; - } - - rlcP->vt_rst += 1; - pdu = get_free_mem_block (rlcP->pdu_size + sizeof (struct rlc_am_tx_control_pdu_allocation) + GUARD_CRC_LIH_SIZE); - - if ((pdu)) { - ((struct rlc_am_tx_control_pdu_management*) (pdu->data))->rlc_tb_type = RLC_AM_RESET_PDU_TYPE; - header = (struct rlc_am_reset_header*) (&pdu->data[sizeof (struct rlc_am_tx_control_pdu_allocation)]); - header->byte1 = RLC_PDU_TYPE_RESET | (rlcP->reset_sequence_number << 3); -#ifdef DEBUG_RESET - msg ("\n******************************************************************\n"); - msg ("[RLC_AM][RB %d] TX RESET RSN %d VT(RST) %d frame %d\n", rlcP->rb_id, rlcP->reset_sequence_number, rlcP->vt_rst, Mac_rlc_xface->frame); - msg ("\n******************************************************************\n"); -#endif - // HFNI NOT IMPLEMENTED NOW needed only for cyphering - /*header->hfni[0] = 0; - header->hfni[1] = 0; - header->hfni[2] = 0; - */ - list_add_head (pdu, &rlcP->control); - rlc_am_fsm_notify_event (rlcP, RLC_AM_TRANSMIT_RESET_EVENT); // not yet submitted to lower layers - - } else { - msg ("[RLC_AM][RB %d] ERROR SEND RESET OUT OF MEMORY ERROR\n", rlcP->rb_id); - } - } -} - -//----------------------------------------------------------------------------- -void -send_reset_ack_pdu (uint8_t rsnP, struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - mem_block_t* pdu; - struct rlc_am_reset_header* header; - - /* From 3GPP TS 25.322 V5.0.0 (2002-03) - RESET ACK PDU contents to set - The Receiver shall: - - set the hyper frame number indicator field (HFNI) to the currently highest used HFN (DL HFN when the RESET - ACK PDU is sent by UTRAN or UL HFN when the RESET ACK PDU is sent by the UE); - - set the RSN field to the same value as in the corresponding received RESET PDU. - */ - if ((pdu = get_free_mem_block (rlcP->pdu_size + sizeof (struct rlc_am_tx_control_pdu_allocation) + GUARD_CRC_LIH_SIZE))) { -#ifdef DEBUG_RESET - msg ("\n******************************************************************\n"); - msg ("[RLC_AM][RB %d] TX RESET ACK RSN %d frame %d\n", rlcP->rb_id, rsnP, Mac_rlc_xface->frame); - msg ("\n******************************************************************\n"); -#endif - ((struct rlc_am_tx_control_pdu_management*) (pdu->data))->rlc_tb_type = RLC_AM_RESET_ACK_PDU_TYPE; - header = (struct rlc_am_reset_header*) (&pdu->data[sizeof (struct rlc_am_tx_control_pdu_allocation)]); - header->byte1 = RLC_PDU_TYPE_RESET_ACK | (rsnP << 3); - list_add_head (pdu, &rlcP->control); - } - -#ifdef DEBUG_RESET - - else { - msg ("[RLC_AM][RB %d] SEND RESET ACK OUT OF MEMORY ERROR\n", rlcP->rb_id); - } - -#endif -} - -//----------------------------------------------------------------------------- -void -process_reset_ack (mem_block_t* pduP, struct rlc_am_reset_header* controlP, struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - /* from 3GPP TS 25.322 V5.0.0 (2002-03) - Upon reception of a RESET ACK PDU, the Sender shall: - - if the Sender has already transmitted a RESET PDU which has not been yet acknowledged by a RESET ACK - PDU: - - if the received RSN value is the same as the one in the corresponding RESET PDU: - - set the HFN value (DL HFN when the RESET ACK PDU is received in UE or UL HFN when the RESET - ACK PDU is received in UTRAN) to the HFNI field of the received RESET ACK PDU; - - reset the state variables described in subclause 9.4 to their initial values; - - stop all the timers described in subclause 9.5; - - reset configurable parameters to their configured values; - - discard all RLC PDUs in the receiving side of the AM RLC entity; - - discard all RLC SDUs that were transmitted before the reset in the transmitting side of the AM RLC - entity; - - increase with one the UL HFN and DL HFN, and the updated HFN values shall be used for the first - transmitted and received AMD PDUs after the reset procedure; - - - otherwise (if the received RSN value is not the same as the one in the corresponding RESET PDU): - - discard the RESET ACK PDU; - - - otherwise (if the Sender has not transmitted a RESET PDU which has not been yet acknowledged by a RESET - ACK PDU): - - discard the RESET ACK PDU. - - NOTE: If the TFC selection exchange has been initiated by sending the RLC Entity Info parameter to MAC, the - RLC entity may delay the RLC SDUs discard in the transmitting side until the end of the next TTI. - */ - if (rlc_am_fsm_notify_event (rlcP, RLC_AM_RECEIVE_RESET_ACK_EVENT)) { - if (((controlP->byte1 & RLC_AM_RESET_SEQUENCE_NUMBER_MASK) >> 3) == rlcP->reset_sequence_number) { -#ifdef DEBUG_RESET - msg ("\n******************************************************************\n"); - msg ("[RLC_AM][RB %d] RX RESET ACK RSN %d frame %d\n", rlcP->rb_id, ((controlP->byte1 & RLC_AM_RESET_SEQUENCE_NUMBER_MASK) >> 3), Mac_rlc_xface->frame); - msg ("\n******************************************************************\n"); -#endif - rlc_am_reset_state_variables (rlcP); - reset_rlc_am (rlcP); - umts_stop_all_timers (&rlcP->rlc_am_timer_list); - rlcP->timer_rst = NULL; - } - -#ifdef DEBUG_RESET - - else { - msg ("\n******************************************************************\n"); - msg ("[RLC_AM][RB %d] RX RESET ACK WRONG RSN %d != %d frame %d\n", rlcP->rb_id, (controlP->byte1 & RLC_AM_RESET_SEQUENCE_NUMBER_MASK) >> 3, - rlcP->reset_sequence_number, Mac_rlc_xface->frame); - msg ("\n******************************************************************\n"); - } - -#endif - } - -#ifdef DEBUG_RESET - - else { - msg ("\n******************************************************************\n"); - msg ("[RLC_AM][RB %d] RX RESET ACK NOT EXPECTED frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame); - msg ("\n******************************************************************\n"); - } - -#endif - msg("RLC AM RESET EXIT\n"); -} - -//----------------------------------------------------------------------------- -void -process_reset (mem_block_t* pduP, struct rlc_am_reset_header* controlP, struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - uint8_t rsn; - uint8_t saved_vt_rst; - /* From 25.322 V5.0.0 (2002-03) - Reception of the RESET PDU by the Receiver - Upon reception of a RESET PDU the Receiver shall: - - if the RSN value in the RESET PDU is the same as the RSN value in the last received RESET PDU: - - only submit a RESET ACK PDU to the lower layer with the contents set exactly as in the last transmitted - RESET ACK PDU (i.e., in this case the RLC entity is not reset). - - - if the RESET PDU is the first RESET PDU received since the entity was (re-)established or the RSN value is - different from the RSN value in the last received RESET PDU: - - submit a RESET ACK PDU to the lower layer with the content set as specified in subclause 11.4.3.1; - - reset the state variables described in subclause 9.4 except VT(RST) to their initial values; - - stop all the timers described in subclause 9.5 except Timer_RST; - - reset configurable parameters to their configured values; - - discard all RLC PDUs in the receiving side of the AM RLC entity; - - discard all RLC SDUs that were transmitted before the reset in the transmitting side of the AM RLC entity; - - set the HFN (DL HFN when the RESET PDU is received in UE or UL HFN when the RESET PDU is - received in UTRAN) equal to the HFNI field in the received RESET PDU; - - increase with one the UL HFN and DL HFN, and the updated HFN values shall be used for the first - transmitted and received AMD PDUs after the reset procedure. - NOTE: If the TFC selection exchange has been initiated by sending the RLC Entity Info parameter to MAC, the - RLC entity may delay the RLC SDUs discard in the transmitting side of the AM RLC entity until the end - of the next TTI. - - Reception of the RESET PDU by the Sender - Upon reception of a RESET PDU, the Sender shall: - - submit a RESET ACK PDU to the lower layer with the content set as specified in subclause 11.4.3.1; - - reset the state variables described in subclause 9.4 except VT(RST) to their initial values; - - stop all the timers described in subclause 9.5 except Timer_RST; - - reset configurable parameters to their configured values; - - discard all RLC PDUs in the receiving side of the AM RLC entity; - - discard all RLC SDUs that were transmitted before the reset in the transmitting side of the AM RLC entity; - - set the HFN (DL HFN when the RESET PDU is received in UE or UL HFN when the RESET PDU is received - in UTRAN) equal to the HFNI field in the received RESET PDU; - - increase with one the UL HFN and DL HFN, and the updated HFN values shall be used for the first transmitted - and received AMD PDUs after the reset procedure. - NOTE: If the TFC selection exchange has been initiated by sending the RLC Entity Info parameter to MAC, the - RLC entity may delay the RLC SDUs discard in the transmitting side until the end of the next TTI. - - */ - rsn = (controlP->byte1 & RLC_AM_RESET_SEQUENCE_NUMBER_MASK) >> 3; - - if ((rlcP->protocol_state & RLC_RESET_PENDING_STATE)) { -#ifdef DEBUG_RESET - msg ("\n******************************************************************\n"); - msg ("[RLC_AM][RB %d] RX RESET RSN %d frame %d\n", rlcP->rb_id, rsn, Mac_rlc_xface->frame); - msg ("\n******************************************************************\n"); -#endif - rlc_am_fsm_notify_event (rlcP, RLC_AM_RECEIVE_RESET_EVENT); - // sender - saved_vt_rst = rlcP->vt_rst; - reset_rlc_am (rlcP); - rlcP->vt_rst = saved_vt_rst; - rlcP->last_received_rsn = rsn; - send_reset_ack_pdu (rsn, rlcP); - - // NOT IN SPECS, BUT IF SENDER RECEIVE A RESET, IT DISCARDS ALL CONTROL PDU IN ITS BUFFER - // SO IF THE RESET PDU WAS STILL IN THE RLC BUFFERS...IT IS DROPPED AND THE RESET TIMER CAN NOT - // BE STARTED (BY SUCCESSFULL TX ACK OF MAC LAYER), SO REARM THE TIMER AND SCHEDULE A NEW RESET - // PDU FOR TRANSMISSION - if (!(rlcP->timer_rst)) { - umts_stop_all_timers (&rlcP->rlc_am_timer_list); - rlc_am_reset_time_out (rlcP, NULL); - - } else { - umts_stop_all_timers_except (&rlcP->rlc_am_timer_list, rlc_am_reset_time_out); - } - - } else { - // receiver -#ifdef DEBUG_RESET - msg ("\n******************************************************************\n"); - msg ("[RLC_AM][RB %d] RX RESET RSN %d frame %d\n", rlcP->rb_id, rsn, Mac_rlc_xface->frame); - msg ("\n******************************************************************\n"); -#endif - - if (rlcP->last_received_rsn == rsn) { //last_received_rsn initialized to -1 when RLC start -#ifdef DEBUG_RESET - msg ("\n******************************************************************\n"); - msg ("[RLC_AM][RB %d] RX RESET RSN %d SAME RSN RECEIVED LAST RESET, SEND RESET ACK frame %d \n", rlcP->rb_id, rsn, Mac_rlc_xface->frame); - msg ("\n******************************************************************\n"); -#endif - send_reset_ack_pdu (rsn, rlcP); // rsn start to zero - return; - } - - rlc_am_fsm_notify_event (rlcP, RLC_AM_RECEIVE_RESET_EVENT); - saved_vt_rst = rlcP->vt_rst; - reset_rlc_am (rlcP); - rlcP->vt_rst = saved_vt_rst; - rlcP->last_received_rsn = rsn; - send_reset_ack_pdu (rsn, rlcP); - umts_stop_all_timers (&rlcP->rlc_am_timer_list); - rlcP->timer_rst = NULL; - } -} - -//----------------------------------------------------------------------------- -void -reset_rlc_am (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - int index; - - for (index = 0; index < rlcP->size_input_sdus_buffer; index++) { - if (rlcP->input_sdus[index]) { - if (!(rlcP->data_plane)) { -#ifdef DEBUG_RLC_AM_SEND_CONFIRM - msg ("[RLC_AM][RB %d][CONFIRM] SDU MUI %d LOST IN RESET\n", rlcP->rb_id, ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[index]->data))->mui); -#endif - rlc_data_conf (0, rlcP->rb_id, ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[index]->data))->mui, RLC_TX_CONFIRM_FAILURE, rlcP->data_plane); - } - - free_mem_block (rlcP->input_sdus[index]); - rlcP->input_sdus[index] = NULL; - } - } - - rlc_am_reset_state_variables (rlcP); - rlc_am_discard_all_pdus (rlcP); -#ifdef DEBUG_RESET - msg ("[RLC_AM][RB %d] RESETED\n", rlcP->rb_id); - //display_mem_load(); - //msg("sdu_conf_segmented : %p\n" , rlcP->sdu_conf_segmented.head); - //msg("sdu_discard_segmented : %p\n", rlcP->sdu_discard_segmented.head); - //msg("sdu_discarded : %p\n" , rlcP->sdu_discarded.head); - //msg("discard_procedures : %p\n" , rlcP->discard_procedures.head); - //check_mem_area(mem); -#endif -} diff --git a/openair2/LAYER2/RLC/AM/rlc_am_reset_proto_extern.h b/openair2/LAYER2/RLC/AM/rlc_am_reset_proto_extern.h deleted file mode 100755 index 6780d4614534be069da2532ef2d1f8822665aa96..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_reset_proto_extern.h +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_reset_proto_extern.h - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - ***************************************************************************/ -# ifndef __RLC_AM_RESET_PROTO_EXTERN_H__ -# define __RLC_AM_RESET_PROTO_EXTERN_H__ -//----------------------------------------------------------------------------- -# include "rlc_am_entity.h" -# include "rlc_am_structs.h" -//----------------------------------------------------------------------------- -extern void rlc_am_reset_time_out (struct rlc_am_entity *rlcP, mem_block_t * not_usedP); -extern void send_reset_ack_pdu (uint8_t rsnP, struct rlc_am_entity *rlcP); -extern void send_reset_pdu (struct rlc_am_entity *rlcP); -extern void reset_rlc_am (struct rlc_am_entity *rlcP); -extern void process_reset_ack (mem_block_t * pduP, struct rlc_am_reset_header *controlP, struct rlc_am_entity *rlcP); -extern void process_reset (mem_block_t * pduP, struct rlc_am_reset_header *controlP, struct rlc_am_entity *rlcP); -# endif diff --git a/openair2/LAYER2/RLC/AM/rlc_am_retrans.c b/openair2/LAYER2/RLC/AM/rlc_am_retrans.c deleted file mode 100755 index 3d270d030991ced958f06c4f10f976ea36cb1d0b..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_retrans.c +++ /dev/null @@ -1,777 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_retrans.c - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - ***************************************************************************/ -#define RLC_AM_C -#include "rtos_header.h" -#include "platform_types.h" -//----------------------------------------------------------------------------- -#include "rlc.h" -#include "rlc_am_entity.h" -#include "rlc_am_errno.h" -#include "rlc_am_constants.h" -#include "rlc_am_structs.h" -#include "rlc_am_discard_notif_proto_extern.h" -#include "rlc_am_util_proto_extern.h" -#include "rlc_am_reset_proto_extern.h" -#include "rlc_am_proto_extern.h" -#include "rlc_am_util_proto_extern.h" -#include "rlc_primitives.h" -#include "list.h" -#include "LAYER2/MAC/extern.h" -//#define DEBUG_RETRANSMISSION -//#define DEBUG_ACK -//#define DEBUG_RESET -//#define DEBUG_BITMAP -//#define DEBUG_LIST -//----------------------------------------------------------------------------- -inline int16_t retransmission_buffer_management_ack (struct rlc_am_entity* rlcP, uint8_t* sufiP, uint8_t byte_alignedP, - int16_t* first_error_indicated_snP); -inline uint8_t* retransmission_buffer_management_bitmap (struct rlc_am_entity* rlcP, uint8_t* bitmap_sufiP, uint8_t byte_alignedP, - int16_t* first_error_indicated_snP); -inline uint8_t* retransmission_buffer_management_list (struct rlc_am_entity* rlcP, uint8_t* bitmap_sufiP, uint8_t byte_alignedP, - int16_t* first_error_indicated_snP); -inline void free_retransmission_buffer (struct rlc_am_entity* rlcP, uint16_t indexP); -inline void free_retransmission_buffer_no_confirmation (struct rlc_am_entity* rlcP, uint16_t indexP); -inline void insert_into_retransmission_buffer (struct rlc_am_entity* rlcP, uint16_t indexP, mem_block_t* pduP); -inline uint8_t retransmit_pdu (struct rlc_am_entity* rlcP, uint16_t snP); -inline uint8_t add_to_transmission_buffer_unack_pdu (struct rlc_am_entity* rlcP, int16_t* nb_pdu_to_transmit); -//----------------------------------------------------------------------------- -/* - * remove all mem_block_t(s) having sn <= snP - */ -int16_t -retransmission_buffer_management_ack (struct rlc_am_entity* rlcP, uint8_t* sufiP, uint8_t byte_alignedP, int16_t* first_error_indicated_snP) -{ - //----------------------------------------------------------------------------- - uint16_t lsn; // sequence number acknowledged - uint16_t current_sn; - uint16_t upper_bound; - int16_t current_index; - uint8_t tmp; - - // get LSN field; - if (byte_alignedP) { - // get next 12 bits; - lsn = (*sufiP++ & 0x0F); - lsn = lsn << 8; - lsn += *sufiP; - - } else { - // get next 12 bits; - sufiP++; - lsn = *sufiP++; - lsn = lsn << 4; - tmp = *sufiP; - lsn |= (tmp >> 4); - } - -#ifdef DEBUG_ACK - msg ("[RLC_AM][RB %d][ACK] RX SUFI ACK 0x%04X VT(A) 0x%04X VT(S) 0x%04X VT(MS) 0x%04X\n", rlcP->rb_id, lsn, rlcP->vt_a, rlcP->vt_s, rlcP->vt_ms); -#endif - current_sn = rlcP->vt_a; - - // From 3GPP TS 25.322 V4.3.0 - // LSN acknowledges the reception of all PDUs with "Sequence Number" < LSN (Last Sequence Number) - // that are not indicated to be erroneous in earlier parts of the STATUS PDU. - // This means that if the LSN is set to a value greater than VR(R), all erroneous PDUs shall - // be included in the same STATUS PDU - // and if the LSN is set to VR(R), the erroneous PDUs can be split into several STATUS PDUs. - // At the transmitter, if the value of the LSN =< the value of the first error indicated - // in the STATUS PDU, VT(A) will be updated according to the LSN, - // otherwise VT(A) will be updated according to the first error indicated in the STATUS PDU. - // VT(A) is only updated based on STATUS PDUs where ACK SUFI (or MRW_ACK SUFI) is included. - // The LSN shall not be set to a value > VR(H) nor < VR(R). - //-------------------------; - // if ack lsn <= first error => vt_a = lsn; - // else vt_a = first error indicated; - // check lsn is valid - if (rlc_am_comp_sn (rlcP, rlcP->vt_a, lsn, rlcP->vt_a) >= 0) { - if (*first_error_indicated_snP >= 0) { - if (rlc_am_comp_sn (rlcP, rlcP->vt_a, lsn, (uint16_t) * first_error_indicated_snP) <= 0) { -#ifdef DEBUG_ACK - msg ("[RLC_AM][RB %d][ACK] VT(A) 0x%04X -> 0x%04X VT(S) 0x%04X CASE LSN <= FIRST PDU IN ERROR IN STATUS PDU\n", rlcP->rb_id, rlcP->vt_a, lsn, rlcP->vt_s); -#endif - rlcP->vt_a = lsn; - - } else { -#ifdef DEBUG_ACK - msg ("[RLC_AM][RB %d][ACK] VT(A) 0x%04X -> 0x%04X VT(S) 0x%04X CASE LSN > FIRST PDU IN ERROR IN STATUS PDU \n", rlcP->rb_id, rlcP->vt_a, - (uint16_t) * first_error_indicated_snP, rlcP->vt_s); -#endif - rlcP->vt_a = (uint16_t) * first_error_indicated_snP; - } - - } else { -#ifdef DEBUG_ACK - msg ("[RLC_AM][RB %d][ACK] VT(A) 0x%04X -> 0x%04X VT(S) 0x%04X CASE SUFI ACK ALONE IN CONTROL PDU\n", rlcP->rb_id, rlcP->vt_a, lsn, rlcP->vt_s); -#endif - rlcP->vt_a = lsn; - } - - rlcP->vt_ms = (rlcP->vt_a + rlcP->vt_ws - 1) & SN_12BITS_MASK; - current_index = current_sn % (uint16_t) rlcP->recomputed_configured_tx_window_size; - upper_bound = lsn % (uint16_t) rlcP->recomputed_configured_tx_window_size; - - // remove all matching pdus from retransmission buffer; - while (upper_bound != current_index) { - // free all pdus that have not been stamped as missing; - if (rlcP->retransmission_buffer[current_index] != NULL) { - if (((struct rlc_am_tx_data_pdu_management*) (rlcP->retransmission_buffer[current_index]->data))->ack != RLC_AM_PDU_NACK_EVENT) { -#ifdef DEBUG_ACK - msg ("[RLC_AM][RB %d][ACK] FREE PDU SN 0x%04X BECAUSE FIELD ACK=%d\n", rlcP->rb_id, current_sn, - ((struct rlc_am_tx_data_pdu_management*) (rlcP->retransmission_buffer[current_index]->data))->ack); -#endif - free_retransmission_buffer (rlcP, (uint16_t) current_index); - - } else { -#ifdef DEBUG_ACK - msg ("[RLC_AM][RB %d][ACK] CLEAR NACK EVENT (%d) PDU SN 0x%04X\n", rlcP->rb_id, - ((struct rlc_am_tx_data_pdu_management*) (rlcP->retransmission_buffer[current_index]->data))->ack, - current_sn); -#endif - ((struct rlc_am_tx_data_pdu_management*) (rlcP->retransmission_buffer[current_index]->data))->ack = RLC_AM_PDU_ACK_NO_EVENT; - } - } - - current_sn = (current_sn + 1) & SN_12BITS_MASK; - current_index = current_sn % (uint16_t) rlcP->recomputed_configured_tx_window_size; - } - - /*if (rlcP->retransmission_buffer[current_index] != NULL) { - if (((struct rlc_am_tx_data_pdu_management*)(&rlcP->retransmission_buffer[current_index]->data[sizeof(struct rlc_am_tx_data_pdu_allocation)]))->ack - == RLC_AM_PDU_NACK_EVENT) { - #ifdef DEBUG_ACK - msg("[RLC_AM %p][ACK] CLEAR ACK EVENT PDU SN %04X\n",rlcP, current_sn); - #endif - ((struct rlc_am_tx_data_pdu_management*)(&rlcP->retransmission_buffer[current_index]->data[sizeof(struct rlc_am_tx_data_pdu_allocation)]))->ack = RLC_AM_PDU_ACK_NO_EVENT; - } - } - */ - return lsn; - - } else { -#ifdef DEBUG_RESET - msg ("[RLC_AM][RB %d][ACK] ERROR SUFI ACK INVALID lsn 0x%02X vt(a) 0x%04X vt(s) 0x%04X -> RESET\n", rlcP->rb_id, lsn, rlcP->vt_a, rlcP->vt_s); - //display_protocol_vars_rlc_am(rlcP); -#endif - send_reset_pdu (rlcP); - return (int16_t) (-1); - } -} - -//----------------------------------------------------------------------------- -/* - * remove all mem_block_t(s) correctly received - * retransmit all mem_block_t(s) not correctly received - * @param bitmap_sufiP pointer on byte containing field "sufi type" - * @param byte_alignedP tells if sufi type quartet is on MSByte (1) or LSByte (0) - */ -inline uint8_t* -retransmission_buffer_management_bitmap (struct rlc_am_entity* rlcP, uint8_t* bitmap_sufiP, uint8_t byte_alignedP, int16_t* first_error_indicated_snP) -{ - //----------------------------------------------------------------------------- - uint16_t id_index; - uint16_t fsn; - uint8_t length, tmp; - uint8_t one_pdu_removed = 0; //optim: update vt_a only at the end of the proc - uint8_t bit_mask; - uint8_t end_bit; - - if (byte_alignedP) { - // get next 4 bits : length - length = (*bitmap_sufiP++ & 0x0F) + 1; - // get next 12 bits : FSN - fsn = *bitmap_sufiP++; - fsn = fsn << 4; - tmp = *bitmap_sufiP; - fsn += tmp >> 4; - bit_mask = 8; - - } else { - bitmap_sufiP++; - // get 4 bits length - length = (*bitmap_sufiP >> 4) + 1; - // get next 12 bits : FSN - fsn = *bitmap_sufiP++ & 0x0F; - fsn = fsn << 8; - fsn = fsn + *bitmap_sufiP; - bitmap_sufiP++; - bit_mask = 128; - } - - end_bit = length << 3; // *8 -#ifdef DEBUG_BITMAP - msg ("[RLC_AM][RB %d][BITMAP] SUFI BITMAP fsn 0x%04X length 0x%04X\n", rlcP->rb_id, fsn, length); -#endif - - if (rlc_am_comp_sn (rlcP, rlcP->vt_a, fsn, rlcP->vt_a) >= 0) { - while (end_bit) { - id_index = fsn % (uint16_t) (rlcP->recomputed_configured_tx_window_size); - - // found a matching pdu - if (*bitmap_sufiP & bit_mask) { - // pdu correctly received - // remove it from retransmission buffer - free_retransmission_buffer (rlcP, id_index); - one_pdu_removed = 1; -#ifdef DEBUG_BITMAP - msg ("[RLC_AM][RB %d][BITMAP] SUFI BITMAP ACK 0x%04x \n", rlcP->rb_id, fsn); -#endif - - } else { - // pdu not correctly received; - // retransmit it; -#ifdef DEBUG_BITMAP - msg ("[RLC_AM][RB %d][BITMAP] SUFI BITMAP NACK 0x%04x\n", rlcP->rb_id, fsn); -#endif - - if (rlcP->retransmission_buffer[id_index]) { - ((struct rlc_am_tx_data_pdu_management*) (rlcP->retransmission_buffer[id_index]->data))->ack = RLC_AM_PDU_NACK_EVENT; - retransmit_pdu (rlcP, fsn); - rlcP->stat_tx_retransmit_pdu_by_status += 1; - /* - if (*first_error_indicated_snP == -1) { - *first_error_indicated_snP = fsn; - } - */ - } - - if (*first_error_indicated_snP == -1) { -#ifdef DEBUG_BITMAP - msg ("[RLC_AM][RB %d][BITMAP] FIRST ERROR INDICATED 0x%04x\n", rlcP->rb_id, fsn); -#endif - *first_error_indicated_snP = fsn; - } - } - - // inc searched sequence number - fsn++; - fsn = fsn & SN_12BITS_MASK; - bit_mask = bit_mask >> 1; - // remaining nb bits to process - end_bit--; - - if (!bit_mask) { - bit_mask = 128; - bitmap_sufiP++; - } - } - - return bitmap_sufiP; - - } else { -#ifdef DEBUG_RESET - msg ("[RLC_AM][RB %d][BITMAP] ERROR SUFI BITMAP INVALID sn 0x%02X vt(a) 0x%04X vt(s) 0x%04X send RESET requested\n", rlcP->rb_id, fsn, rlcP->vt_a, rlcP->vt_s); -#endif - display_protocol_vars_rlc_am (rlcP); - send_reset_pdu (rlcP); - return bitmap_sufiP; - } -} - -//----------------------------------------------------------------------------- -/* - * retransmit all mem_block_t(s) not correctly received - * @param bitmap_sufiP pointer on byte containing field "sufi type" - * @param byte_alignedP tells if sufi type quartet is on MSByte (1) or LSByte (0) - */ -inline uint8_t* -retransmission_buffer_management_list (struct rlc_am_entity* rlcP, uint8_t* bitmap_sufiP, uint8_t byte_alignedP, int16_t* first_error_indicated_snP) -{ - //----------------------------------------------------------------------------- - uint8_t* p8; - uint16_t start_marking_sn; - uint8_t nb_missing_pdu; - uint8_t nb_pairs; - p8 = bitmap_sufiP; - - if (byte_alignedP) { - nb_pairs = *p8++ & 0X0F; // number of (SNi, Li) pairs in the sufi type LIST the value 0000 - - // is invalid and the list is discarded - if (!nb_pairs) { - p8 = p8 + 2; -#ifdef DEBUG_RESET - msg ("[RLC_AM][RB %d][LIST] ERROR SUFI LIST nb pairs is 0 send RESET requested\n", rlcP->rb_id); -#endif - send_reset_pdu (rlcP); -#ifdef DEBUG_LIST - display_protocol_vars_rlc_am (rlcP); -#endif - return p8; - return p8; - - } else { - while (nb_pairs) { - start_marking_sn = ((uint16_t) (*p8++)) << 4; - start_marking_sn = start_marking_sn | (*p8 >> 4); - nb_missing_pdu = *p8++ & 0X0F; - - if (*first_error_indicated_snP == -1) { - *first_error_indicated_snP = start_marking_sn; -#ifdef DEBUG_LIST - msg ("[RLC_AM][RB %d][LIST] FIRST ERROR INDICATED 0x%04X VT(A) 0x%04X VT(S) 0x%04X\n", rlcP->rb_id, *first_error_indicated_snP, rlcP->vt_a, rlcP->vt_s); -#endif - } - -#ifdef DEBUG_LIST - msg ("[RLC_AM][RB %d][LIST] SUFI LIST SN 0x%04X MISSING %d VT(A) 0x%04X VT(S) 0x%04X\n", rlcP->rb_id, start_marking_sn, nb_missing_pdu, rlcP->vt_a, - rlcP->vt_s); -#endif - - while (nb_missing_pdu) { - if (rlc_am_comp_sn (rlcP, rlcP->vt_a, start_marking_sn, rlcP->vt_a) >= 0) { - if (rlcP->retransmission_buffer[start_marking_sn % rlcP->recomputed_configured_tx_window_size] != NULL) { -#ifdef DEBUG_LIST - msg ("[RLC_AM][RB %d][LIST] MARK SN 0x%04X INDEX 0x%04X TO RLC_AM_PDU_NACK_EVENT\n", rlcP->rb_id, start_marking_sn, - start_marking_sn % rlcP->recomputed_configured_tx_window_size); -#endif - ((struct rlc_am_tx_data_pdu_management*) (rlcP->retransmission_buffer[start_marking_sn % rlcP->recomputed_configured_tx_window_size]->data))->ack = - RLC_AM_PDU_NACK_EVENT; - retransmit_pdu (rlcP, start_marking_sn); - rlcP->stat_tx_retransmit_pdu_by_status += 1; - } - - } else { - send_reset_pdu (rlcP); -#ifdef DEBUG_RESET - msg ("[RLC_AM][RB %d][LIST] ERROR SUFI LIST INVALID SN 0x%02X VT(A) 0x%04X VT(S) 0x%04X send RESET requested \n", rlcP->rb_id, start_marking_sn, rlcP->vt_a, - rlcP->vt_s); -#endif -#ifdef DEBUG_LIST - display_protocol_vars_rlc_am (rlcP); -#endif - return p8; - } - - start_marking_sn = (start_marking_sn + 1) & SN_12BITS_MASK; - nb_missing_pdu--; - } - - nb_pairs--; - } - - return p8; - } - - } else { - p8++; - nb_pairs = *p8 >> 4; // number of (SNi, Li) pairs in the sufi type LIST the value 0000 - - // is invalid and the list is discarded - if (!nb_pairs) { - p8 = p8 + 2; -#ifdef DEBUG_RESET - msg ("[RLC_AM][RB %d][LIST] ERROR SUFI LIST nb pairs is 0 send RESET requested vt(a) 0x%04X vt(s) 0x%04X\n", rlcP->rb_id, rlcP->vt_a, rlcP->vt_s); -#endif - send_reset_pdu (rlcP); -#ifdef DEBUG_LIST - display_protocol_vars_rlc_am (rlcP); -#endif - return p8; - - } else { - while (nb_pairs) { - start_marking_sn = ((uint16_t) (*p8++) & 0x0F) << 8; - start_marking_sn = start_marking_sn | *p8++; - nb_missing_pdu = *p8 >> 4; - - if (*first_error_indicated_snP == -1) { - *first_error_indicated_snP = start_marking_sn; -#ifdef DEBUG_LIST - msg ("[RLC_AM][RB %d][LIST] FIRST ERROR INDICATED 0x%04X VT(A) 0x%04X VT(S) 0x%04X\n", rlcP->rb_id, *first_error_indicated_snP, rlcP->vt_a, rlcP->vt_s); -#endif - } - -#ifdef DEBUG_LIST - msg ("[RLC_AM][RB %d][RETRANSMISSION] SUFI LIST SN 0x%04X MISSING %d VT(A) 0x%04X VT(S) 0x%04X\n", rlcP->rb_id, start_marking_sn, nb_missing_pdu, rlcP->vt_a, - rlcP->vt_s); -#endif - - while (nb_missing_pdu) { - if (rlc_am_comp_sn (rlcP, rlcP->vt_a, start_marking_sn, rlcP->vt_a) >= 0) { - if (rlcP->retransmission_buffer[start_marking_sn % rlcP->recomputed_configured_tx_window_size] != NULL) { -#ifdef DEBUG_LIST - msg ("[RLC_AM][RB %d][LIST] MARK SN 0x%04X INDEX 0x%04X TO RLC_AM_PDU_NACK_EVENT\n", rlcP->rb_id, start_marking_sn, - start_marking_sn % rlcP->recomputed_configured_tx_window_size); -#endif - ((struct rlc_am_tx_data_pdu_management*) (rlcP->retransmission_buffer[start_marking_sn % rlcP->recomputed_configured_tx_window_size]->data))->ack = - RLC_AM_PDU_NACK_EVENT; - retransmit_pdu (rlcP, start_marking_sn); - rlcP->stat_tx_retransmit_pdu_by_status += 1; - } - - } else { - send_reset_pdu (rlcP); -#ifdef DEBUG_RESET - msg ("[RLC_AM][RB %d][LIST] ERROR SUFI LIST invalid sn 0x%02X send RESET requested vt(a) 0x%04X vt(s) 0x%04X\n", rlcP->rb_id, start_marking_sn, rlcP->vt_a, - rlcP->vt_s); -#endif -#ifdef DEBUG_LIST - display_protocol_vars_rlc_am (rlcP); -#endif - return p8; - } - - start_marking_sn = (start_marking_sn + 1) & SN_12BITS_MASK; - nb_missing_pdu--; - } - - nb_pairs--; - } - - return p8; - } - } -} - -//----------------------------------------------------------------------------- -inline void -free_retransmission_buffer (struct rlc_am_entity* rlcP, uint16_t indexP) -{ - //----------------------------------------------------------------------------- - mem_block_t* sdu_confirm; - struct rlc_am_tx_data_pdu_management* pdu; - mem_block_t* le = NULL; - unsigned int index; - unsigned int sdu_index; - index = indexP; - - if (index < (uint16_t) rlcP->recomputed_configured_tx_window_size) { - le = rlcP->retransmission_buffer[index]; - - if (le != NULL) { - // ??? - pdu = (struct rlc_am_tx_data_pdu_management*) (le->data); - - // test if the sender of the sdu requested a confirmation of the reception of the sdu by the receiving RLC - // or if mode discard is on - for (sdu_index = 0; sdu_index < pdu->nb_sdu; sdu_index++) { - if (pdu->sdu[sdu_index] != -1) { // may be discarded - ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[pdu->sdu[sdu_index]]->data))->nb_pdus_ack += 1; - - if ((((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[pdu->sdu[sdu_index]]->data))->nb_pdus_ack == - ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[pdu->sdu[sdu_index]]->data))->nb_pdus) && - (((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[pdu->sdu[sdu_index]]->data))->segmented)) { - if (((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[pdu->sdu[sdu_index]]->data))->confirm) { - // send confirmation to upper layers -#ifdef DEBUG_RLC_AM_SEND_CONFIRM - msg ("[RLC_AM][RB %d][CONFIRM] SDU MUI %d ACK BY PEER\n", rlcP->rb_id, ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[pdu->sdu[sdu_index]]->data))->mui); -#endif - rlc_data_conf (0, rlcP->rb_id, ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[pdu->sdu[sdu_index]]->data))->mui, RLC_TX_CONFIRM_SUCCESSFULL, - rlcP->data_plane); - } - - // FREE SDU : we can remove the sdu if timer based discard and all pdus submitted to lower layers and no confirm running -#ifdef DEBUG_RLC_AM_FREE_SDU - msg ("[RLC_AM][RB %d][RETRANS] FREE PDU INDEX 0x%04X FREE_SDU INDEX 0x%3X\n", rlcP->rb_id, indexP, pdu->sdu[sdu_index]); -#endif - free_mem_block (rlcP->input_sdus[pdu->sdu[sdu_index]]); - rlcP->input_sdus[pdu->sdu[sdu_index]] = NULL; - } - } - } - - // now check if a copy of the pdu is not present in the retransmission_buffer_to_send - if ((pdu->copy)) { - list2_remove_element (pdu->copy, &rlcP->retransmission_buffer_to_send); - free_mem_block (pdu->copy); - } - -#ifdef DEBUG_BUFFER_RETRANSMISSION - msg ("[RLC_AM][RB %d][RETRANSMISSION] FREE PDU INDEX=0x%04X %p\n", rlcP->rb_id, index, le); -#endif - - // if this pdu has been retransmitted, remove its size from buffer occupancy - if (pdu->vt_dat > 0) { - rlcP->buffer_occupancy_retransmission_buffer -= 1; - } - - free_mem_block (le); - rlcP->retransmission_buffer[index] = NULL; - return; - } - -#ifdef DEBUG_BUFFER_RETRANSMISSION - //msg("[RLC_AM %p][RETRANSMISSION] ERROR free_retransmission_buffer() pointer to free is NULL, index in array = %04X\n", rlcP,index); -#endif - return; - } - - msg ("[RLC_AM][RB %d][RETRANSMISSION] ERROR free_retransmission_buffer() invalid index in array decimal %d \n", rlcP->rb_id, index); -} - -//----------------------------------------------------------------------------- -inline void -free_retransmission_buffer_no_confirmation (struct rlc_am_entity* rlcP, uint16_t indexP) -{ - //----------------------------------------------------------------------------- - struct rlc_am_tx_data_pdu_management* pdu; - mem_block_t* le = NULL; - unsigned int index; - unsigned int sdu_index; - index = indexP; - - if (index < (uint16_t) rlcP->recomputed_configured_tx_window_size) { - le = rlcP->retransmission_buffer[index]; - - if (le != NULL) { - pdu = (struct rlc_am_tx_data_pdu_management*) (le->data); - - // test if the sender of the sdu requested a confirmation of the reception of the sdu by the receiving RLC - // or if mode discard is on - for (sdu_index = 0; sdu_index < pdu->nb_sdu; sdu_index++) { - if (pdu->sdu[sdu_index] != -1) { // may be discarded - ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[pdu->sdu[sdu_index]]->data))->nb_pdus_ack += 1; - - if ((((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[pdu->sdu[sdu_index]]->data))->nb_pdus_ack == - ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[pdu->sdu[sdu_index]]->data))->nb_pdus) && - (((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[pdu->sdu[sdu_index]]->data))->segmented)) { - // FREE SDU : we can remove the sdu if timer based discard and all pdus submitted to lower layers and no confirm running -#ifdef DEBUG_RLC_AM_FREE_SDU - msg ("[RLC_AM][RB %d][RETRANS] FREE PDU NO_CONF INDEX 0x%04X FREE_SDU INDEX %d\n", rlcP->rb_id, indexP, pdu->sdu[sdu_index]); -#endif - free_mem_block (rlcP->input_sdus[pdu->sdu[sdu_index]]); - rlcP->input_sdus[pdu->sdu[sdu_index]] = NULL; - } - } - } - - // now check if a copy of the pdu is not present in the retransmission_buffer_to_send - if ((pdu->copy)) { - list2_remove_element (pdu->copy, &rlcP->retransmission_buffer_to_send); - free_mem_block (pdu->copy); - } - -#ifdef DEBUG_BUFFER_RETRANSMISSION - msg ("[RLC_AM][RB %d][RETRANSMISSION] FREE PDU NO_CONF INDEX=0x%04X %p\n", rlcP->rb_id, index, le); -#endif - - // if this pdu has been retransmitted, remove its size from buffer occupancy - if (pdu->vt_dat > 0) { - rlcP->buffer_occupancy_retransmission_buffer -= 1; - } - - free_mem_block (le); - rlcP->retransmission_buffer[index] = NULL; - return; - } - -#ifdef DEBUG_BUFFER_RETRANSMISSION - //msg("[RLC_AM %p][RETRANSMISSION] ERROR free_retransmission_buffer() pointer to free is NULL, index in array = %04X\n", rlcP,index); -#endif - return; - } - - msg ("[RLC_AM][RB %d][RETRANSMISSION] ERROR free_retransmission_buffer() invalid index in array decimal %d \n", rlcP->rb_id, index); -} - -//----------------------------------------------------------------------------- -inline void -insert_into_retransmission_buffer (struct rlc_am_entity* rlcP, uint16_t indexP, mem_block_t* pduP) -{ - //----------------------------------------------------------------------------- - uint16_t index; - index = indexP; - - if (index < (uint16_t) (rlcP->recomputed_configured_tx_window_size)) { - if (rlcP->retransmission_buffer[index]) { -#ifdef DEBUG_BUFFER_RETRANSMISSION - msg ("[RLC_AM][RB %d][RETRANSMISSION] INSERT PDU ERROR SLOT NOT EMPTY %d=0x%04X\n", rlcP->rb_id, index, index); - display_retransmission_buffer (rlcP); -#endif - free_mem_block (rlcP->retransmission_buffer[index]); - } - - rlcP->retransmission_buffer[index] = pduP; -#ifdef DEBUG_BUFFER_RETRANSMISSION - msg ("[RLC_AM][RB %d][RETRANSMISSION] INSERT PDU INDEX=0x%04X %p\n", rlcP->rb_id, indexP, pduP); -#endif - return; - } - - free_mem_block (pduP); - //#ifdef DEBUG_BUFFER_RETRANSMISSION - msg ("[RLC_AM][RB %d][RETRANSMISSION] ERROR INSERT RETRANS INVALID INDEX in array decimal %d\n", rlcP->rb_id, index); - //#endif -} - -//----------------------------------------------------------------------------- -inline uint8_t -retransmit_pdu (struct rlc_am_entity* rlcP, uint16_t snP) -{ - //----------------------------------------------------------------------------- - mem_block_t* pdu, *copy; - struct rlc_am_tx_data_pdu_management* pdu_mngt; - uint16_t index; - - if ((rlcP->protocol_state & RLC_DATA_TRANSFER_READY_STATE)) { - index = snP % rlcP->recomputed_configured_tx_window_size; - pdu = rlcP->retransmission_buffer[index]; - - if (pdu) { - pdu_mngt = (struct rlc_am_tx_data_pdu_management*) (pdu->data); - pdu_mngt->vt_dat += 1; - - // if first retransmission, add to buffer occupancy - if (pdu_mngt->vt_dat == 1) { - rlcP->buffer_occupancy_retransmission_buffer += 1; - } - - if ((pdu_mngt->vt_dat < rlcP->max_dat) || ((rlcP->sdu_discard_mode & SDU_DISCARD_MODE_TIMER_BASED_EXPLICIT))) { - // now check if a copy of the pdu is not already present in the retransmission buffer - if (pdu_mngt->copy == NULL) { - copy = get_free_mem_block (rlcP->pdu_size + sizeof (struct rlc_am_tx_data_pdu_allocation) + GUARD_CRC_LIH_SIZE); - - if (copy) { - memcpy (copy->data, pdu->data, rlcP->pdu_size + sizeof (struct rlc_am_tx_data_pdu_allocation)); - list2_add_tail (copy, &rlcP->retransmission_buffer_to_send); - // make link between the original pdu and its copy - pdu_mngt->copy = copy; - ((struct rlc_am_tx_data_pdu_management*) (copy->data))->copy = pdu; -#ifdef BENCH_QOS_L2 - fprintf (bench_l2, "[PDU RETRANS] FRAME %d SN %d VT_DAT %d RLC-AM %p\n", Mac_rlc_xface->frame, snP, pdu_mngt->vt_dat, rlcP); -#endif -#ifdef DEBUG_RETRANSMISSION - msg ("[RLC_AM][RB %d][RETRANSMISSION] PDU SN = 0x%04X hex VT(DAT) %d frame %d\n", rlcP->rb_id, snP, pdu_mngt->vt_dat, Mac_rlc_xface->frame); -#endif - return 0; - - } else { - msg ("[RLC_AM][RB %d][RETRANSMISSION] ERROR retransmit_pdu() retransmited copy of pdu is NULL index in array %04X\n", rlcP->rb_id, index); - return RLC_AM_OUT_OF_MEMORY_ERROR; - } - - } else { -#ifdef DEBUG_RETRANSMISSION - msg ("[RLC_AM][RB %d][RETRANSMISSION] PDU SN = 0x%04X hex VT(DAT) %d already in retransmission buffer to send\n", rlcP->rb_id, snP, pdu_mngt->vt_dat); -#endif - return RLC_AM_RETRANS_REQ_PDU_DONE_BEFORE; - } - - } else { - if ((rlcP->sdu_discard_mode & SDU_DISCARD_MODE_TIMER_BASED_EXPLICIT)) { - // DO NOTHING - } else if ((rlcP->sdu_discard_mode & RLC_SDU_DISCARD_MAX_DAT_RETRANSMISSION)) { -#ifdef DEBUG_RETRANSMISSION - msg ("[RLC_AM][RB %d][RETRANSMISSION] VT(DAT) %d REACHED MAX_DAT, DISCARD PROCEDURE WILL BE STARTED frame %d\n", rlcP->rb_id, pdu_mngt->vt_dat, - Mac_rlc_xface->frame); -#endif - rlc_am_discard_notify_max_dat_pdu (rlcP, pdu); - - } else { // if No_discard after MaxDat number of retransmissions is used, the sender shall initiate the - // RLC reset procedure when VT(DAT) >= MaxDAT (from 3GPP TS 25.322 V5.0.0 ) - // max transmission reached for this PDU, reset RLC entities -#ifdef DEBUG_RESET - msg ("[RLC_AM][RB %d][RETRANSMISSION] VT(DAT) %d REACHED MAX_DAT, RESET frame %d\n", rlcP->rb_id, pdu_mngt->vt_dat, Mac_rlc_xface->frame); -#endif - send_reset_pdu (rlcP); - } - - return -1; - } - - } else { - return RLC_AM_RETRANS_REQ_PDU_NULL; - } - } - - return -1; -} - -//----------------------------------------------------------------------------- -void -rlc_am_get_not_acknowledged_pdu_optimized (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - uint16_t vt_dat_min = 255; - uint16_t sn; - uint16_t sn_min; - mem_block_t* pdu; - struct rlc_am_tx_data_pdu_management* pdu_mngt; - sn = rlcP->vt_s; - sn_min = sn; - - while (sn != rlcP->vt_a) { - sn = (sn - 1) & SN_12BITS_MASK; - pdu = rlcP->retransmission_buffer[sn % rlcP->recomputed_configured_tx_window_size]; - - if ((pdu)) { - pdu_mngt = (struct rlc_am_tx_data_pdu_management*) (pdu->data); - - if (pdu_mngt->vt_dat < vt_dat_min) { - sn_min = sn; - vt_dat_min = pdu_mngt->vt_dat; - } - } - } - - if (rlcP->retransmission_buffer[sn_min % rlcP->recomputed_configured_tx_window_size]) { - retransmit_pdu (rlcP, sn_min); - rlcP->stat_tx_retransmit_pdu_unblock += 1; - } -} - - -//----------------------------------------------------------------------------- -void -rlc_am_get_not_acknowledged_pdu (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - uint16_t sn; - sn = rlcP->vt_s; - - while (sn != rlcP->vt_a) { - sn = (sn - 1) & SN_12BITS_MASK; - - if (rlcP->retransmission_buffer[sn % rlcP->recomputed_configured_tx_window_size]) { - retransmit_pdu (rlcP, sn); - rlcP->stat_tx_retransmit_pdu_unblock += 1; - return; - } - } -} - -//----------------------------------------------------------------------------- -void -rlc_am_get_not_acknowledged_pdu_vt_s_minus_1 (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - if (rlcP->retransmission_buffer[((rlcP->vt_s - 1) & SN_12BITS_MASK) % rlcP->recomputed_configured_tx_window_size]) { - retransmit_pdu (rlcP, (rlcP->vt_s - 1) & SN_12BITS_MASK); - rlcP->stat_tx_retransmit_pdu_unblock += 1; - } -} diff --git a/openair2/LAYER2/RLC/AM/rlc_am_retrans_proto_extern.h b/openair2/LAYER2/RLC/AM/rlc_am_retrans_proto_extern.h deleted file mode 100755 index f0ea17c98553ccba87a56b54d961c23728086dd9..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_retrans_proto_extern.h +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_retrans_proto_extern.h - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - ***************************************************************************/ -# ifndef __RLC_AM_RETRANS_PROTO_EXTERN_H__ -# define __RLC_AM_RETRANS_PROTO_EXTERN_H__ -//----------------------------------------------------------------------------- -# include "rlc_am_entity.h" -# include "rlc_am_structs.h" -# include "rlc_am_constants.h" -//----------------------------------------------------------------------------- -extern int16_t retransmission_buffer_management_ack (struct rlc_am_entity *rlcP, uint8_t * sufiP, uint8_t byte_alignedP, int16_t * first_error_indicated_snP); -extern uint8_t *retransmission_buffer_management_bitmap (struct rlc_am_entity *rlcP, uint8_t * bitmap_sufiP, uint8_t byte_alignedP, int16_t * first_error_indicated_snP); -extern uint8_t *retransmission_buffer_management_list (struct rlc_am_entity *rlcP, uint8_t * bitmap_sufiP, uint8_t byte_alignedP, int16_t * first_error_indicated_snP); -extern void free_retransmission_buffer (struct rlc_am_entity *rlcP, uint16_t indexP); -extern void free_retransmission_buffer_no_confirmation (struct rlc_am_entity *rlcP, uint16_t indexP); -extern void insert_into_retransmission_buffer (struct rlc_am_entity *rlcP, uint16_t indexP, mem_block_t * pduP); -extern uint8_t retransmit_pdu (struct rlc_am_entity *rlcP, uint16_t snP); -extern void rlc_am_get_not_acknowledged_pdu (struct rlc_am_entity *rlcP); -extern void rlc_am_get_not_acknowledged_pdu_vt_s_minus_1 (struct rlc_am_entity *rlcP); -extern void rlc_am_get_not_acknowledged_pdu_optimized (struct rlc_am_entity *rlcP); -# endif diff --git a/openair2/LAYER2/RLC/AM/rlc_am_segment.c b/openair2/LAYER2/RLC/AM/rlc_am_segment.c deleted file mode 100755 index 69255a6a344b339241e9065010044cb15300f60e..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_segment.c +++ /dev/null @@ -1,616 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_segment.c - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - ***************************************************************************/ -#include "rtos_header.h" -//----------------------------------------------------------------------------- -#include "list.h" -#include "rlc_am_entity.h" -#include "rlc_am_structs.h" -#include "rlc_am_constants.h" -#include "rlc_primitives.h" -#include "mem_block.h" - -//#define DEBUG_RLC_AM_SEGMENT -//#define DEBUG_RLC_AM_SEGMENT_FILL_DATA -//#define DEBUG_MEM_MNGT -//----------------------------------------------------------------------------- -mem_block_t* rlc_am_segment_15 (struct rlc_am_entity* rlcP); -mem_block_t* rlc_am_segment_7 (struct rlc_am_entity* rlcP); -//----------------------------------------------------------------------------- -inline void -rlc_am_encode_pdu_15 (struct rlc_am_pdu_header* rlc_headerP, struct rlc_am_tx_data_pdu_management* pdu_mngtP, uint16_t* li_arrayP, uint8_t nb_liP) -{ - //----------------------------------------------------------------------------- - uint8_t li_index; -#ifdef DEBUG_RLC_AM_SEGMENT - int index; - msg ("[RLC_AM] SEGMENT_15 PDU SET LIs: "); - - for (index = 0; index < nb_liP; index++) { - msg ("%04X ", li_arrayP[index]); - } - - msg ("\n"); -#endif - rlc_headerP->byte1 = RLC_DC_DATA_PDU; - rlc_headerP->byte2 = 0; - nb_liP = nb_liP << 1; - pdu_mngtP->payload = (uint8_t*) ((uint32_t) (&rlc_headerP->li_data_7[nb_liP])); - - if (nb_liP) { - rlc_headerP->byte2 |= RLC_E_NEXT_FIELD_IS_LI_E; - li_index = 0; - - // COPY LI - while (li_index < nb_liP) { - rlc_headerP->li_data_7[li_index] = li_arrayP[li_index >> 1] >> 8; - li_index += 1; - rlc_headerP->li_data_7[li_index] = li_arrayP[li_index >> 1] | RLC_E_NEXT_FIELD_IS_LI_E; - li_index += 1; - } - - rlc_headerP->li_data_7[li_index - 1] = rlc_headerP->li_data_7[li_index - 1] ^ (uint8_t) RLC_E_NEXT_FIELD_IS_LI_E; - } -} - -//----------------------------------------------------------------------------- -inline void -rlc_am_encode_pdu_7 (struct rlc_am_pdu_header* rlc_headerP, struct rlc_am_tx_data_pdu_management* pdu_mngtP, uint16_t* li_arrayP, uint8_t nb_liP) -{ - //----------------------------------------------------------------------------- - uint8_t li_index; -#ifdef DEBUG_RLC_AM_SEGMENT - int index; - msg ("[RLC_AM] SEGMENT_7 PDU %p SET LIs: ", pdu_mngtP); - - for (index = 0; index < nb_liP; index++) { - msg ("%04X ", li_arrayP[index]); - } - - msg ("\n"); -#endif - rlc_headerP->byte1 = RLC_DC_DATA_PDU; - rlc_headerP->byte2 = 0; - pdu_mngtP->payload = (uint8_t*) ((uint32_t) (&rlc_headerP->li_data_7[nb_liP])); - - if (nb_liP) { - rlc_headerP->byte2 |= RLC_E_NEXT_FIELD_IS_LI_E; - li_index = 0; - - // COPY LI - while (li_index < nb_liP) { - rlc_headerP->li_data_7[li_index] = (uint8_t) (li_arrayP[li_index]) | RLC_E_NEXT_FIELD_IS_LI_E; - li_index += 1; - } - - rlc_headerP->li_data_7[li_index - 1] = rlc_headerP->li_data_7[li_index - 1] ^ (uint8_t) RLC_E_NEXT_FIELD_IS_LI_E; - } -} - -//----------------------------------------------------------------------------- -inline void -rlc_am_fill_pdu (mem_block_t* pduP, list_t* segmented_sdusP) -{ - //----------------------------------------------------------------------------- - mem_block_t* sdu; - uint8_t* data_sdu; - uint8_t* data_pdu; - struct rlc_am_pdu_header* rlc_header; - struct rlc_am_tx_data_pdu_management* pdu_mngt; - struct rlc_am_tx_sdu_management* sdu_mngt; - int continue_fill; - uint16_t pdu_remaining_size; - uint16_t sdu_available_size; - sdu = NULL; - pdu_mngt = (struct rlc_am_tx_data_pdu_management*) (pduP->data); - rlc_header = (struct rlc_am_pdu_header*) (pdu_mngt->first_byte); - pdu_remaining_size = pdu_mngt->data_size; - data_pdu = (uint8_t*) pdu_mngt->payload; -#ifdef DEBUG_RLC_AM_SEGMENT_FILL_DATA - msg ("[RLC_AM] SEGMENT FILL GET PDU %p REMAINING SIZE=%d\n", pduP, pdu_remaining_size); -#endif - continue_fill = 1; - - while ((continue_fill)) { - // fill the pdu with data of sdu - if (sdu == NULL) { - sdu = list_remove_head (segmented_sdusP); - - if (sdu == NULL) { - return; // case pdu only 2 LIs : exactly_filled or one_byte_short + paddind - } - - sdu_mngt = (struct rlc_am_tx_sdu_management*) (sdu->data); - data_sdu = &sdu->data[sizeof (struct rlc_am_tx_sdu_management) + sdu_mngt->sdu_segmented_size]; - sdu_available_size = sdu_mngt->sdu_size - sdu_mngt->sdu_remaining_size - sdu_mngt->sdu_segmented_size; -#ifdef DEBUG_RLC_AM_SEGMENT_FILL_DATA - msg ("[RLC_AM] SEGMENT FILL GET SDU %p AVAILABLE_SZ=%d (SZ %d REMAIN_SZ %d SEGMENT_SZ %d)\n", - sdu, sdu_available_size, sdu_mngt->sdu_size, sdu_mngt->sdu_remaining_size, sdu_mngt->sdu_segmented_size); -#endif - } - - // copy the whole remaining data of the sdu in the remaining area of the pdu - if (pdu_remaining_size >= sdu_available_size) { - memcpy (data_pdu, data_sdu, sdu_available_size); -#ifdef DEBUG_RLC_AM_SEGMENT_FILL_DATA - msg ("[RLC_AM] SEGMENT FILL PDU %p WITH SDU %p %p <- %p %d bytes (SZ %d REMAIN_SZ %d SEGMENT_SZ %d)\n", - pduP, sdu, data_pdu, data_sdu, sdu_available_size, sdu_mngt->sdu_size, sdu_mngt->sdu_remaining_size, sdu_mngt->sdu_segmented_size); -#endif - pdu_remaining_size -= sdu_available_size; - sdu_mngt->sdu_segmented_size += sdu_available_size; - data_pdu = (uint8_t*) ((uint32_t) data_pdu + sdu_available_size); - sdu_available_size = 0; - // dispatch the sdu - sdu = NULL; - - // dispatch the pdu - if (pdu_remaining_size == 0) { - continue_fill = 0; - - } else { - } - - // copy some data of the sdu in the whole remaining area of the pdu - } else { - memcpy (data_pdu, data_sdu, pdu_remaining_size); -#ifdef DEBUG_RLC_AM_SEGMENT_FILL_DATA - msg ("[RLC_AM] SEGMENT FILL PDU %p WITH SDU %p %p <- %p %d bytes (SZ %d REMAIN_SZ %d SEGMENT_SZ %d)\n", - pduP, sdu, data_pdu, data_sdu, pdu_remaining_size, sdu_mngt->sdu_size, sdu_mngt->sdu_remaining_size, sdu_mngt->sdu_segmented_size); -#endif - sdu_mngt->sdu_segmented_size += pdu_remaining_size; - sdu_available_size -= pdu_remaining_size; - data_sdu = (uint8_t*) ((uint32_t) data_sdu + (uint32_t) pdu_remaining_size); - continue_fill = 0; - pdu_remaining_size = 0; - } - } - - list_free (segmented_sdusP); -} - -//----------------------------------------------------------------------------- -mem_block_t* -rlc_am_segment_15 (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - list_t segmented_sdus; // the copying of sdu data is done after identification of all LIs to put in pdu - struct rlc_am_tx_sdu_management* sdu_mngt; - struct rlc_am_tx_data_pdu_management* pdu_mngt; - struct rlc_am_pdu_header* rlc_header; - mem_block_t* pdu; - int continue_segment = 1; - int16_t pdu_remaining_size; - uint8_t li_index = 0; - pdu = NULL; - list_init (&segmented_sdus, NULL); // param string identifying the list is NULL - - while ((rlcP->input_sdus[rlcP->current_sdu_index]) && (continue_segment)) { - sdu_mngt = ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[rlcP->current_sdu_index]->data)); - - if (!(sdu_mngt->segmented)) { - // pdu management - if (!(pdu)) { - if (!(pdu = get_free_mem_block (rlcP->pdu_size + sizeof (struct rlc_am_tx_data_pdu_allocation) + GUARD_CRC_LIH_SIZE))) { -#ifdef DEBUG_MEM_MNGT - msg ("[RLC_AM][RB %d][SEGMENT] ERROR COULD NOT GET NEW PDU, EXIT\n", rlcP->rb_id); -#endif - return NULL; - } - - li_index = 0; - pdu_remaining_size = rlcP->pdu_size - 2; // 2= size of header, minimum - pdu_mngt = (struct rlc_am_tx_data_pdu_management*) (pdu->data); - memset (pdu->data, 0, sizeof (struct rlc_am_tx_data_pdu_allocation)); - pdu_mngt->rlc_tb_type = RLC_AM_DATA_PDU_TYPE; - pdu_mngt->first_byte = &pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]; - rlc_header = (struct rlc_am_pdu_header*) (pdu_mngt->first_byte); - } - - if (sdu_mngt->sdu_remaining_size > 0) { // think RLC_LI_LAST_PDU_ONE_BYTE_SHORT, RLC_LI_LAST_PDU_EXACTLY_FILLED - if ((pdu_remaining_size - sdu_mngt->sdu_remaining_size) < 0) { - pdu_mngt->data_size += pdu_remaining_size; - rlc_am_encode_pdu_15 (rlc_header, pdu_mngt, rlcP->li, li_index); - continue_segment = 0; - sdu_mngt->sdu_remaining_size = sdu_mngt->sdu_remaining_size - pdu_remaining_size; - sdu_mngt->nb_pdus += 1; - pdu_mngt->sdu[pdu_mngt->nb_sdu++] = rlcP->current_sdu_index; - - } else { - // From 3GPP TS 25.322 V4.2.0 (2001-09) p28 - // If "SDU discard with explicit signalling" is configured: - // - an AMD PDU can contain a maximum number of 15 "Length Indicators" indicating the end - // of 15 corresponding SDUs; and - // - the rest of the AMD PDU space shall be used as padding or as piggybacked STATUS PDU. - // implementation limitation : we limit the number of li to 15 even if - // no "SDU discard with explicit signalling" is configured. - if (li_index >= 14) { - rlcP->li[li_index++] = RLC_LI_PDU_PADDING; - rlc_am_encode_pdu_15 (rlc_header, pdu_mngt, rlcP->li, li_index); - continue_segment = 0; - sdu_mngt->no_new_sdu_segmented_in_last_pdu = 1; - - } else { // nb li have not reached the limit - if ((pdu_remaining_size - sdu_mngt->sdu_remaining_size) >= 2) { - pdu_remaining_size = pdu_remaining_size - sdu_mngt->sdu_remaining_size - 2; // size of li length - pdu_mngt->data_size += sdu_mngt->sdu_remaining_size; - sdu_mngt->li_index_for_discard = li_index; - rlcP->li[li_index++] = sdu_mngt->sdu_remaining_size << 1; - sdu_mngt->sdu_remaining_size = 0; - sdu_mngt->segmented = 1; - sdu_mngt->nb_pdus += 1; - pdu_mngt->sdu[pdu_mngt->nb_sdu++] = rlcP->current_sdu_index; - pdu_mngt->last_pdu_of_sdu += 1; - list_add_tail_eurecom (rlcP->input_sdus[rlcP->current_sdu_index], &segmented_sdus); - rlcP->buffer_occupancy -= sdu_mngt->sdu_size; - rlcP->nb_sdu -= 1; - rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % rlcP->size_input_sdus_buffer; - //} else the while loop continue with the same pdu - - } else if ((pdu_remaining_size - sdu_mngt->sdu_remaining_size) == 0) { - // from 3GPP TS 25.322 V4.2.0 - //In the case where the end of the last segment of an RLC SDU exactly ends at the end of - // a PDU and there is no "Length Indicator" that indicates the end of the RLC SDU: - // - if 7-bit "Length Indicator" is used: - // - a "Length Indicator" with value "000 0000" shall be placed as the first "Length - // Indicator" in the following PDU; - // - if 15-bit "Length Indicator" is used: - // - a "Length Indicator" with value "000 0000 0000 0000" shall be placed as the first - // "Length Indicator" in the following PDU. - pdu_mngt->data_size += pdu_remaining_size; - rlc_am_encode_pdu_15 (rlc_header, pdu_mngt, rlcP->li, li_index); - continue_segment = 0; - sdu_mngt->sdu_remaining_size = 0; - sdu_mngt->nb_pdus += 1; - pdu_mngt->sdu[pdu_mngt->nb_sdu++] = rlcP->current_sdu_index; - list_add_tail_eurecom (rlcP->input_sdus[rlcP->current_sdu_index], &segmented_sdus); - rlcP->li_exactly_filled_to_add_in_next_pdu = 1; - - } else if ((pdu_remaining_size - sdu_mngt->sdu_remaining_size) == 1) { // one byte remaining - // from 3GPP TS 25.322 V4.2.0 - // In the case where a PDU contains a 15-bit "Length Indicator" indicating that an RLC SDU ends with - // one octet left in the PDU, the last octet of this PDU shall: - // - be padded by the Sender and ignored by the Receiver though there is no "Length Indicator" - // indicating the existence of Padding; and - // - not be filled with the first octet of the next RLC SDU data. - // In the case where 15-bit "Length Indicators" are used for the previous PDU and - // the last segment of an RLC SDU is one octet short of exactly filling the PDU: - // - if a 15-bit "Length Indicator" is used for the following PDU: - // - the "Length Indicator" with value "111 1111 1111 1011" shall be placed as - // the first "Length Indicator" in the following PDU; - // - the remaining one octet in the previous PDU shall be padded by the Sender - // and ignored at the Receiver though there is no "Length Indicator" indicating - // the existence of Padding; - // - in case this SDU was the last one to be transmitted: - // - a RLC PDU consisting of an RLC Header with "Length Indicator" - // "111 1111 1111 1011" followed by a padding "Length Indicator" and padding - // may be transmitted; - pdu_mngt->data_size += pdu_remaining_size; - rlc_am_encode_pdu_15 (rlc_header, pdu_mngt, rlcP->li, li_index); - continue_segment = 0; - sdu_mngt->sdu_remaining_size = 0; - sdu_mngt->nb_pdus += 1; - pdu_mngt->sdu[pdu_mngt->nb_sdu++] = rlcP->current_sdu_index; - list_add_tail_eurecom (rlcP->input_sdus[rlcP->current_sdu_index], &segmented_sdus); - rlcP->li_one_byte_short_to_add_in_next_pdu = 1; - } - } - } - - // management of previous pdu - // In the case where 15-bit "Length Indicators" are used for the previous PDU and - // the last segmentof an RLC SDU is one octet short of exactly filling the PDU: - // - if a 15-bit "Length Indicator" is used for the following PDU: - // - the "Length Indicator" with value "111 1111 1111 1011" shall be placed - // as the first "Length Indicator" in the following PDU; - // - the remaining one octet in the previous PDU shall be padded by the Sender - // and ignored at the Receiver though there is no "Length Indicator" indicating - // the existence of Padding; - // - in case this SDU was the last one to be transmitted: - // - a RLC PDU consisting of an RLC Header with "Length Indicator" - // "111 1111 1111 1011" followed by a padding "Length Indicator" and padding - // may be transmitted; - - } else if ((rlcP->li_one_byte_short_to_add_in_next_pdu)) { - sdu_mngt->li_index_for_discard = li_index; - rlcP->li[li_index++] = RLC_LI_LAST_PDU_ONE_BYTE_SHORT; - rlcP->li_one_byte_short_to_add_in_next_pdu = 0; - sdu_mngt->segmented = 1; - pdu_remaining_size -= 2; - pdu_mngt->last_pdu_of_sdu += 1; - pdu_mngt->sdu[pdu_mngt->nb_sdu++] = rlcP->current_sdu_index; - sdu_mngt->nb_pdus += 1; - rlcP->buffer_occupancy -= sdu_mngt->sdu_size; - rlcP->nb_sdu -= 1; - rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % rlcP->size_input_sdus_buffer; - - } else if ((rlcP->li_exactly_filled_to_add_in_next_pdu)) { - sdu_mngt->li_index_for_discard = li_index; - rlcP->li[li_index++] = RLC_LI_LAST_PDU_EXACTLY_FILLED; - rlcP->li_exactly_filled_to_add_in_next_pdu = 0; - sdu_mngt->segmented = 1; - pdu_remaining_size -= 2; - pdu_mngt->last_pdu_of_sdu += 1; - pdu_mngt->sdu[pdu_mngt->nb_sdu++] = rlcP->current_sdu_index; - sdu_mngt->nb_pdus += 1; - rlcP->buffer_occupancy -= sdu_mngt->sdu_size; - rlcP->nb_sdu -= 1; - rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % rlcP->size_input_sdus_buffer; - } - } - - if (sdu_mngt->sdu_remaining_size > 0) { - list_add_tail_eurecom (rlcP->input_sdus[rlcP->current_sdu_index], &segmented_sdus); - } - } - - if ((pdu)) { - if ((continue_segment > 0)) { // means pdu not totaly filled - if (pdu_remaining_size >= 2) { - rlcP->li[li_index++] = RLC_LI_PDU_PADDING; - sdu_mngt->no_new_sdu_segmented_in_last_pdu = 1; - - } else if (pdu_remaining_size == 0) { - rlcP->li_exactly_filled_to_add_in_next_pdu = 1; - - } else if (pdu_remaining_size == 1) { - rlcP->li_one_byte_short_to_add_in_next_pdu = 1; - } - - rlc_am_encode_pdu_15 (rlc_header, pdu_mngt, rlcP->li, li_index); - } - - rlc_am_fill_pdu (pdu, &segmented_sdus); - - } else { - // patch for max dat discard : avoid waiting sdu pointed by current_sdu_index <> NULL - // (this sdu may have been segmented not at all then discarded) - while ((rlcP->next_sdu_index != rlcP->current_sdu_index) && (rlcP->input_sdus[rlcP->current_sdu_index] == NULL)) { - rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % rlcP->size_input_sdus_buffer; - rlcP->nb_sdu -= 1; - } - } - - return pdu; -} - -//----------------------------------------------------------------------------- -mem_block_t* -rlc_am_segment_7 (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - list_t segmented_sdus; // the copying of sdu data is done after identification of all LIs to put in pdu - struct rlc_am_tx_sdu_management* sdu_mngt = NULL; - struct rlc_am_tx_data_pdu_management* pdu_mngt; - struct rlc_am_pdu_header* rlc_header; - mem_block_t* pdu = NULL; - int continue_segment = 1; - int16_t pdu_remaining_size; - uint8_t li_index = 0; - list_init (&segmented_sdus, NULL); // param string identifying the list is NULL - - while ((rlcP->input_sdus[rlcP->current_sdu_index]) && (continue_segment)) { - sdu_mngt = ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[rlcP->current_sdu_index]->data)); - - if (!(sdu_mngt->segmented)) { -#ifdef DEBUG_RLC_AM_SEGMENT - msg ("[RLC_AM][RB %d] SEGMENT GET NEW SDU %p INDEX %d AVAILABLE SIZE %d Bytes\n", rlcP->rb_id, sdu_mngt, rlcP->current_sdu_index, sdu_mngt->sdu_remaining_size); -#endif - - if (!(pdu)) { - // pdu management - if (!(pdu = get_free_mem_block (rlcP->pdu_size + sizeof (struct rlc_am_tx_data_pdu_allocation) + GUARD_CRC_LIH_SIZE))) { -#ifdef DEBUG_MEM_MNGT - msg ("[RLC_AM][RB %d][SEGMENT7] ERROR COULD NOT GET NEW PDU, EXIT\n", rlcP->rb_id); -#endif - return NULL; - } - - li_index = 0; - pdu_remaining_size = rlcP->pdu_size - 2; // 2= size of header, minimum - pdu_mngt = (struct rlc_am_tx_data_pdu_management*) (pdu->data); - memset (pdu->data, 0, sizeof (struct rlc_am_tx_data_pdu_allocation)); - pdu_mngt->rlc_tb_type = RLC_AM_DATA_PDU_TYPE; - pdu_mngt->first_byte = &pdu->data[sizeof (struct rlc_am_tx_data_pdu_allocation)]; - rlc_header = (struct rlc_am_pdu_header*) (pdu_mngt->first_byte); - - if ((rlcP->li_exactly_filled_to_add_in_next_pdu)) { - pdu_remaining_size -= 1; - } - -#ifdef DEBUG_RLC_AM_SEGMENT - msg ("[RLC_AM][RB %d][SEGMENT7] CONSTRUCT NEW PDU %p %p\n", rlcP->rb_id, pdu, pdu_mngt); -#endif - } - - if (sdu_mngt->sdu_remaining_size > 0) { - msg("sdu_mngt->sdu_remaining_size %d\n",sdu_mngt->sdu_remaining_size); - - if ((pdu_remaining_size - sdu_mngt->sdu_remaining_size) < 0) { - pdu_mngt->data_size += pdu_remaining_size; - rlcP->buffer_occupancy -= pdu_remaining_size; - sdu_mngt->nb_pdus += 1; - pdu_mngt->sdu[pdu_mngt->nb_sdu++] = rlcP->current_sdu_index; - rlc_am_encode_pdu_7 (rlc_header, pdu_mngt, rlcP->li, li_index); - continue_segment = 0; - sdu_mngt->sdu_remaining_size = sdu_mngt->sdu_remaining_size - pdu_remaining_size; - pdu_remaining_size = 0; -#ifdef DEBUG_RLC_AM_SEGMENT - msg ("[RLC_AM][RB %d][SEGMENT7] PDU %p %p FILLED WITH SDU index %d SDU REMAINING %d\n", rlcP->rb_id, pdu, pdu_mngt, rlcP->current_sdu_index, - sdu_mngt->sdu_remaining_size); -#endif - - } else { - // From 3GPP TS 25.322 V4.2.0 (2001-09) p28 - // If "SDU discard with explicit signalling" is configured: - // - an AMD PDU can contain a maximum number of 15 "Length Indicators" indicating the end - // of 15 corresponding SDUs; and - // - the rest of the AMD PDU space shall be used as padding or as piggybacked STATUS PDU. - // implementation limitation : we limit the number of li to 15 even if - // no "SDU discard with explicit signalling" is configured. - if (li_index >= 14) { - rlcP->li[li_index++] = RLC_LI_PDU_PADDING; - rlc_am_encode_pdu_7 (rlc_header, pdu_mngt, rlcP->li, li_index); - continue_segment = 0; - sdu_mngt->no_new_sdu_segmented_in_last_pdu = 1; -#ifdef DEBUG_RLC_AM_SEGMENT - msg ("[RLC_AM][RB %d][SEGMENT7] NB MAX LI REACHED\n", rlcP->rb_id); -#endif - - } else { // nb li have not reached the limit - if ((pdu_remaining_size - sdu_mngt->sdu_remaining_size) >= 1) { - pdu_remaining_size = pdu_remaining_size - sdu_mngt->sdu_remaining_size - 1; // size of li length - pdu_mngt->data_size += sdu_mngt->sdu_remaining_size; - sdu_mngt->li_index_for_discard = li_index; - rlcP->li[li_index++] = sdu_mngt->sdu_remaining_size << 1; - rlcP->buffer_occupancy -= sdu_mngt->sdu_remaining_size; - sdu_mngt->sdu_remaining_size = 0; - sdu_mngt->segmented = 1; - sdu_mngt->nb_pdus += 1; - pdu_mngt->sdu[pdu_mngt->nb_sdu++] = rlcP->current_sdu_index; - pdu_mngt->last_pdu_of_sdu += 1; - list_add_tail_eurecom (rlcP->input_sdus[rlcP->current_sdu_index], &segmented_sdus); - rlcP->nb_sdu -= 1; -#ifdef DEBUG_RLC_AM_SEGMENT - msg ("[RLC_AM][RB %d][SEGMENT7] SDU index %d->%d ENDING IN PDU %p %p PDU REMAINING SIZE %d\n", rlcP->rb_id, - rlcP->current_sdu_index, (rlcP->current_sdu_index + 1) % rlcP->size_input_sdus_buffer, pdu, pdu_mngt, pdu_remaining_size); -#endif - rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % rlcP->size_input_sdus_buffer; - - // case where Li length exactly ends the pdu - if (pdu_remaining_size == 0) { - continue_segment = 0; - rlc_am_encode_pdu_7 (rlc_header, pdu_mngt, rlcP->li, li_index); - } - - /* - } else { // else:if (!last_sdu) - } // the while loop continue with the same pdu */ - - } else if ((pdu_remaining_size - sdu_mngt->sdu_remaining_size) == 0) { - // from 3GPP TS 25.322 V4.2.0 - //In the case where the end of the last segment of an RLC SDU exactly ends at the end of - // a PDU and there is no "Length Indicator" that indicates the end of the RLC SDU: - // - if 7-bit "Length Indicator" is used: - // - a "Length Indicator" with value "000 0000" shall be placed as the first "Length - // Indicator" in the following PDU; - // - if 15-bit "Length Indicator" is used: - // - a "Length Indicator" with value "000 0000 0000 0000" shall be placed as the first - // "Length Indicator" in the following PDU. - pdu_mngt->data_size += pdu_remaining_size; - rlc_am_encode_pdu_7 (rlc_header, pdu_mngt, rlcP->li, li_index); - continue_segment = 0; - rlcP->buffer_occupancy -= sdu_mngt->sdu_remaining_size; - sdu_mngt->sdu_remaining_size = 0; - pdu_remaining_size = 0; - sdu_mngt->nb_pdus += 1; - pdu_mngt->sdu[pdu_mngt->nb_sdu++] = rlcP->current_sdu_index; - list_add_tail_eurecom (rlcP->input_sdus[rlcP->current_sdu_index], &segmented_sdus); - rlcP->li_exactly_filled_to_add_in_next_pdu = 1; -#ifdef DEBUG_RLC_AM_SEGMENT - msg ("[RLC_AM][RB %d][SEGMENT7] SDU index %d EXACTLY ENDING IN PDU %p %p\n", rlcP->rb_id, rlcP->current_sdu_index, pdu, pdu_mngt); -#endif - } - } - } - - // management of previous pdu - // In the case where 15-bit "Length Indicators" are used for the previous PDU and the - // last segment of an RLC SDU is one octet short of exactly filling the PDU: - // - if a 15-bit "Length Indicator" is used for the following PDU: - // - the "Length Indicator" with value "111 1111 1111 1011" shall be placed as - // the first "Length Indicator" in the following PDU; - // - the remaining one octet in the previous PDU shall be padded by the Sender and - // ignored at the Receiver - // though there is no "Length Indicator" indicating the existence of Padding; - // - in case this SDU was the last one to be transmitted: - // - a RLC PDU consisting of an RLC Header with "Length Indicator" - // "111 1111 1111 1011" followed by a padding "Length Indicator" and padding - // may be transmitted; - // - if a 7-bit "Length Indicator" is used for the following PDU: - // - if RLC is configured for UM mode: - // - the "Length Indicator" with value "000 0000" shall be placed as the first - // "Length indicator" in the following PDU and its SN shall be incremented by 2 - // before it is transmitted. - - } else if ((rlcP->li_exactly_filled_to_add_in_next_pdu)) { - sdu_mngt->li_index_for_discard = li_index; - rlcP->li[li_index++] = RLC_LI_LAST_PDU_EXACTLY_FILLED; - rlcP->li_exactly_filled_to_add_in_next_pdu = 0; - sdu_mngt->segmented = 1; - //pdu_remaining_size -= 1; - pdu_mngt->last_pdu_of_sdu += 1; - pdu_mngt->sdu[pdu_mngt->nb_sdu++] = rlcP->current_sdu_index; - sdu_mngt->nb_pdus += 1; - //rlcP->buffer_occupancy -= sdu_mngt->sdu_size; - rlcP->nb_sdu -= 1; -#ifdef DEBUG_RLC_AM_SEGMENT - msg ("[RLC_AM][RB %d][SEGMENT7] RLC_LI_LAST_PDU_EXACTLY_FILLED -> PDU %p, %p, sdu index %d->%d \n", rlcP->rb_id, pdu, pdu_mngt, - rlcP->current_sdu_index, (rlcP->current_sdu_index + 1) % rlcP->size_input_sdus_buffer); -#endif - rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % rlcP->size_input_sdus_buffer; - } - } - - if (sdu_mngt->sdu_remaining_size > 0) { - list_add_tail_eurecom (rlcP->input_sdus[rlcP->current_sdu_index], &segmented_sdus); - } - } - - if ((pdu)) { - if ((continue_segment > 0)) { // means pdu not totaly filled - if (pdu_remaining_size >= 1) { - rlcP->li[li_index++] = RLC_LI_PDU_PADDING; - sdu_mngt->no_new_sdu_segmented_in_last_pdu = 1; - - } else { - rlcP->li_exactly_filled_to_add_in_next_pdu = 1; - } - - rlc_am_encode_pdu_7 (rlc_header, pdu_mngt, rlcP->li, li_index); - } - - rlc_am_fill_pdu (pdu, &segmented_sdus); - - } else { - // patch for max dat discard : avoid waiting sdu pointed by current_sdu_index <> NULL - // (this sdu may have been segmented not at all then discarded) - while ((rlcP->next_sdu_index != rlcP->current_sdu_index) && (rlcP->input_sdus[rlcP->current_sdu_index] == NULL)) { - rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % rlcP->size_input_sdus_buffer; - rlcP->nb_sdu -= 1; - } - } - - return pdu; -} diff --git a/openair2/LAYER2/RLC/AM/rlc_am_segment_proto_extern.h b/openair2/LAYER2/RLC/AM/rlc_am_segment_proto_extern.h deleted file mode 100755 index 59146d67007a80f7e3a804183cc180611af894ee..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_segment_proto_extern.h +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_segment_proto_extern.h - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - ***************************************************************************/ -# ifndef __RLC_AM_SEGMENT_PROTO_EXTERN_H__ -# define __RLC_AM_SEGMENT_PROTO_EXTERN_H__ -//----------------------------------------------------------------------------- -# include "rlc_am_entity.h" -# include "rlc_am_structs.h" -# include "rlc_am_constants.h" -# include "list.h" -//----------------------------------------------------------------------------- -extern inline uint16_t rlc_am_get_next_sn (struct rlc_am_entity *rlcP, uint16_t snP); -extern inline int rlc_am_sn_in_tx_window (struct rlc_am_entity *rlcP, uint16_t snP); - -extern inline void rlc_am_sdu_confirm_map_register_pdu (mem_block_t * pduP, struct rlc_am_pdu_header *rlc_headerP, mem_block_t * sdu_header_confirm_copyP); - -extern inline void rlc_am_sdu_discard_map_register_pdu (mem_block_t * pduP, struct rlc_am_pdu_header *rlc_headerP, mem_block_t * sdu_header_discard_copyP); - -extern mem_block_t *rlc_am_segment_15 (struct rlc_am_entity *rlcP); -extern mem_block_t *rlc_am_segment_7 (struct rlc_am_entity *rlcP); -# endif diff --git a/openair2/LAYER2/RLC/AM/rlc_am_status.c b/openair2/LAYER2/RLC/AM/rlc_am_status.c deleted file mode 100755 index c74f2a44e83eea120f2095818f3e232c452a7f71..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_status.c +++ /dev/null @@ -1,659 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_status.c - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - ***************************************************************************/ -#include "rtos_header.h" -#include "platform_types.h" -//----------------------------------------------------------------------------- -#include "rlc_am_entity.h" -#include "rlc_am_retrans_proto_extern.h" -#include "rlc_am_status_proto_extern.h" -#include "rlc_am_discard_rx_proto_extern.h" -#include "rlc_am_proto_extern.h" -#include "rlc_am_util_proto_extern.h" -#include "LAYER2/MAC/extern.h" -//#define DEBUG_CREATE_STATUS -//#define DEBUG_CREATE_STATUS_SUFI -//#define PROCESS_STATUS - -void rlc_am_write_sufi_no_more_in_control_pdu (uint8_t * dataP, uint8_t byte_alignedP); -void rlc_am_write_sufi_ack_in_control_pdu (uint8_t * dataP, uint16_t snP, uint8_t byte_alignedP); -int rlc_am_send_status (struct rlc_am_entity *rlcP); -int rlc_am_create_status_pdu (struct rlc_am_entity *rlcP, list_t* listP); -void rlc_am_find_holes (struct rlc_am_entity *rlcP); -//----------------------------------------------------------------------------- -void -rlc_am_write_sufi_no_more_in_control_pdu (uint8_t * dataP, uint8_t byte_alignedP) -{ - //----------------------------------------------------------------------------- - -#ifdef DEBUG_CREATE_STATUS_SUFI - msg ("[RLC_AM][STATUS] GENERATE SUFI NO_MORE\n"); -#endif - - if (!byte_alignedP) { - *dataP = (*dataP & 0xF0) | RLC_AM_SUFI_NO_MORE; - } else { - *dataP = RLC_AM_SUFI_NO_MORE << 4; - } -} - -//----------------------------------------------------------------------------- -void -rlc_am_write_sufi_ack_in_control_pdu (uint8_t * dataP, uint16_t snP, uint8_t byte_alignedP) -{ - //----------------------------------------------------------------------------- - -#ifdef DEBUG_CREATE_STATUS_SUFI - msg ("[RLC_AM][STATUS] GENERATE SUFI ACK 0x%04X\n", snP); -#endif - - if (!byte_alignedP) { - *dataP = (*dataP & 0xF0) | RLC_AM_SUFI_ACK; - dataP++; - *dataP++ = (uint8_t) (snP >> 4); - *dataP = (uint8_t) (snP << 4); - } else { - *dataP = RLC_AM_SUFI_ACK << 4; - *dataP = *dataP | (uint8_t) (snP >> 8); - dataP++; - *dataP = (uint8_t) (snP); - } -} - -//----------------------------------------------------------------------------- -int -rlc_am_send_status (struct rlc_am_entity *rlcP) -{ - //----------------------------------------------------------------------------- - -#ifdef DEBUG_CREATE_STATUS - display_receiver_buffer (rlcP); -#endif - - if (rlcP->timer_status_prohibit > 0) { - if (rlcP->running_timer_status_prohibit > Mac_rlc_xface->frame) { - //msg ("[RLC_AM][RB %d][STATUS] PREVENTED CREATE_STATUS_PDU %d %d\n", rlcP->rb_id, rlcP->running_timer_status_prohibit, Mac_rlc_xface->frame); - - return 0; - } else { - //msg ("[RLC_AM][RB %d][STATUS] AUTHORIZE CREATE_STATUS_PDU frame %d timer %d timeout %d\n", rlcP->rb_id, Mac_rlc_xface->frame, rlcP->running_timer_status_prohibit, rlcP->timer_status_prohibit); - rlcP->running_timer_status_prohibit = rlcP->timer_status_prohibit/10 + Mac_rlc_xface->frame; - } - } - - // sufis are created in a array of sufi in rlc struct; - rlc_am_find_holes (rlcP); - - // create pdu with array of sufi previously generated; - return rlc_am_create_status_pdu (rlcP, &rlcP->control); -} - -//----------------------------------------------------------------------------- -int -rlc_am_create_status_pdu (struct rlc_am_entity *rlcP, list_t * listP) -{ - //----------------------------------------------------------------------------- - mem_block_t *mb = NULL; - struct rlc_am_status_header *pdu; - uint8_t *p8; - uint8_t *tmp; - int hole_index = 0; - signed int pdu_remaining_size; // remaining size for SUFIs BITMAP, LIST, RLIST, WINDOW - int current_sn; - signed int remaining_sn; - int pdu_status_count = 0; - int length_sufi; - int16_t last_hole_sn = -1; - uint8_t byte_aligned; - - - remaining_sn = rlcP->vr_h - rlcP->vr_r; - - if (remaining_sn < 0) { - remaining_sn = remaining_sn + SN_12BITS_MASK + 1; - } - - while ((rlcP->holes[hole_index].valid) && (remaining_sn)) { - - - if (!(mb)) { - mb = get_free_mem_block (rlcP->pdu_size + sizeof (struct rlc_am_tx_control_pdu_allocation) + GUARD_CRC_LIH_SIZE); - - if (mb == NULL) { - msg ("[MEM_MNGT] ERROR create_status_pdu() no free blocks\n"); - return 0; - } else { - pdu_status_count += 1; -#ifdef DEBUG_CREATE_STATUS - msg ("[RLC_AM][RB %d][STATUS] CREATE_STATUS_PDU %d\n", rlcP->rb_id, pdu_status_count); -#endif - memset (mb->data, 0, rlcP->pdu_size + sizeof (struct rlc_am_tx_control_pdu_allocation)); - - if (pdu_status_count == 1) { - ((struct rlc_am_tx_control_pdu_management *) (mb->data))->rlc_tb_type = RLC_AM_FIRST_STATUS_PDU_TYPE; - } else { - ((struct rlc_am_tx_control_pdu_management *) (mb->data))->rlc_tb_type = RLC_AM_STATUS_PDU_TYPE; - } - - pdu = (struct rlc_am_status_header *) (&mb->data[sizeof (struct rlc_am_tx_control_pdu_allocation)]); - pdu->byte1 = RLC_PDU_TYPE_STATUS; - p8 = &(pdu->byte1); - - // if first pdu of status include ack field - if (pdu_status_count == 1) { - pdu_remaining_size = (rlcP->pdu_size << 3) - 16; //-4(PDU_TYPE) -12(SUFI ACK) - current_sn = rlcP->ack_sn; - remaining_sn = rlcP->vr_h - rlcP->vr_r; - - if (remaining_sn < 0) { - remaining_sn = remaining_sn + SN_12BITS_MASK + 1; - } - } else { - pdu_remaining_size = (rlcP->pdu_size << 3) - 8; //-4(PDU_TYPE) - 4(SUFI NO_MORE) - } - - byte_aligned = 0; - } - } - - // From 3GPP TS 25.322 V4.2.0 : - // Which SUFI fields to use is implementation dependent,... - // IMPLEMENTATION : KEEP GENERATION OF SUFI SIMPLE : GENERATE ONLY LIST - if (pdu_remaining_size >= RLC_AM_SUFI_LIST_SIZE_MIN) { - //---------------------------------- - // generate LIST - //---------------------------------- - if (!byte_aligned) { - *p8 = *p8 | RLC_AM_SUFI_LIST; - p8 = p8 + 1; - tmp = p8; //(*tmp = length_sufi << 4) when we will know length - length_sufi = 0; - pdu_remaining_size -= 8; - - while ((length_sufi < 15) && (pdu_remaining_size >= 16) && (rlcP->holes[hole_index].valid) && (rlcP->nb_missing_pdus)) { -#ifdef DEBUG_CREATE_STATUS - msg ("[RLC_AM][RB %d][STATUS] GENERATE SUFI LIST HOLE START 0x%04X ", rlcP->rb_id, rlcP->holes[hole_index].fsn); -#endif - *p8 = *p8 | (rlcP->holes[hole_index].fsn >> 8); - p8 += 1; - *p8 = rlcP->holes[hole_index].fsn; - p8 += 1; - - if (rlcP->holes[hole_index].length <= 15) { - *p8 = rlcP->holes[hole_index].length << 4; -#ifdef DEBUG_CREATE_STATUS - msg ("LENGTH %d\n", rlcP->holes[hole_index].length); -#endif - rlcP->nb_missing_pdus -= rlcP->holes[hole_index].length; - current_sn = (rlcP->holes[hole_index].fsn + rlcP->holes[hole_index].length) & SN_12BITS_MASK; - last_hole_sn = (rlcP->holes[hole_index].fsn + rlcP->holes[hole_index].length) & SN_12BITS_MASK; - hole_index += 1; - } else { -#ifdef DEBUG_CREATE_STATUS - msg ("LENGTH 15\n"); -#endif - *p8 = 0xF0; - rlcP->nb_missing_pdus -= 15; - rlcP->holes[hole_index].length -= 15; - rlcP->holes[hole_index].fsn = (rlcP->holes[hole_index].fsn + 15) & SN_12BITS_MASK; - current_sn = rlcP->holes[hole_index].fsn; - } - - length_sufi += 1; - pdu_remaining_size -= 16; - } - - *tmp = *tmp | (length_sufi << 4); - } else { - *p8 = RLC_AM_SUFI_LIST << 4; - tmp = p8; //(*tmp = length_sufi) when we will know length - p8 = p8 + 1; - length_sufi = 0; - pdu_remaining_size -= 8; - - while ((length_sufi < 15) && (pdu_remaining_size >= 16) && (rlcP->holes[hole_index].valid) && (rlcP->nb_missing_pdus)) { -#ifdef DEBUG_CREATE_STATUS - msg ("[RLC_AM][RB %d][STATUS] GENERATE SUFI LIST HOLE START 0x%04X ", rlcP->rb_id, rlcP->holes[hole_index].fsn); -#endif - *p8 = rlcP->holes[hole_index].fsn >> 4; - p8 += 1; - *p8 = rlcP->holes[hole_index].fsn << 4; - - if (rlcP->holes[hole_index].length <= 15) { -#ifdef DEBUG_CREATE_STATUS - msg ("LENGTH %d\n", rlcP->holes[hole_index].length); -#endif - *p8 = *p8 | rlcP->holes[hole_index].length; - p8 += 1; - rlcP->nb_missing_pdus -= rlcP->holes[hole_index].length; - current_sn = (rlcP->holes[hole_index].fsn + rlcP->holes[hole_index].length) & SN_12BITS_MASK; - last_hole_sn = (rlcP->holes[hole_index].fsn + rlcP->holes[hole_index].length) & SN_12BITS_MASK; - hole_index += 1; - } else { -#ifdef DEBUG_CREATE_STATUS - msg ("LENGTH 15\n"); -#endif - *p8 = *p8 | 15; - p8 += 1; - rlcP->nb_missing_pdus -= 15; - rlcP->holes[hole_index].length -= 15; - rlcP->holes[hole_index].fsn = (rlcP->holes[hole_index].fsn + 15) & SN_12BITS_MASK; - } - - length_sufi += 1; - pdu_remaining_size -= 16; - } - - *tmp = *tmp | length_sufi; - } - } else { - // it is not possible to write a sufi LIST in this control pdu, so close this pdu (write ACK or NO_MORE) - if (pdu_status_count == 1) { - //rlc_am_write_sufi_ack_in_control_pdu(p8, current_sn, byte_aligned); - if (last_hole_sn > 0) { - rlc_am_write_sufi_ack_in_control_pdu (p8, last_hole_sn, byte_aligned); - } else { - rlc_am_write_sufi_ack_in_control_pdu (p8, current_sn, byte_aligned); - } - } else { - rlc_am_write_sufi_no_more_in_control_pdu (p8, byte_aligned); - } - - //hole_index += 1; - list_add_tail_eurecom (mb, listP); - mb = NULL; - } - - remaining_sn = rlcP->vr_h - current_sn; - - if (remaining_sn < 0) { - remaining_sn = remaining_sn + SN_12BITS_MASK + 1; - } - } - - if ((mb == NULL) && !(pdu_status_count)) { - mb = get_free_mem_block (rlcP->pdu_size + sizeof (struct rlc_am_tx_control_pdu_allocation) + GUARD_CRC_LIH_SIZE); - - if (mb == NULL) { - msg ("[MEM_MNGT] ERROR create_status_pdu() no free blocks\n"); - return 0; - } else { -#ifdef DEBUG_CREATE_STATUS - msg ("[RLC_AM][RB %d][STATUS] CREATE_STATUS_PDU %d\n", rlcP->rb_id, pdu_status_count + 1); -#endif - memset (mb->data, 0, rlcP->pdu_size + sizeof (struct rlc_am_tx_control_pdu_allocation)); - ((struct rlc_am_tx_control_pdu_management *) (mb->data))->rlc_tb_type = RLC_AM_FIRST_STATUS_PDU_TYPE | RLC_AM_LAST_STATUS_PDU_TYPE; - - pdu = (struct rlc_am_status_header *) (&mb->data[sizeof (struct rlc_am_tx_control_pdu_allocation)]); - pdu->byte1 = RLC_PDU_TYPE_STATUS; - p8 = &(pdu->byte1); - byte_aligned = 0; - rlc_am_write_sufi_ack_in_control_pdu (p8, rlcP->ack_sn, byte_aligned); - list_add_tail_eurecom (mb, listP); - } - } else if ((mb)) { - // if first pdu insert ack field updated to last sn referenced by a sufi in this pdu - // else insert no more field - ((struct rlc_am_tx_control_pdu_management *) (mb->data))->rlc_tb_type |= RLC_AM_LAST_STATUS_PDU_TYPE; - - if (pdu_status_count == 1) { - if (last_hole_sn > 0) { - rlc_am_write_sufi_ack_in_control_pdu (p8, last_hole_sn, byte_aligned); - } else { - rlc_am_write_sufi_ack_in_control_pdu (p8, current_sn, byte_aligned); - } - } else { - rlc_am_write_sufi_no_more_in_control_pdu (p8, byte_aligned); - } - - list_add_tail_eurecom (mb, listP); - } - - return 1; -} - -//----------------------------------------------------------------------------- -void -rlc_am_find_holes (struct rlc_am_entity *rlcP) -{ - //----------------------------------------------------------------------------- - - - uint16_t working_sn, working_sn_index; - uint16_t end_sn; - uint16_t distance; - int hole_index; - - //-------------------------------------------------- - // FIND HOLES - //-------------------------------------------------- - hole_index = 0; - // ACK - rlcP->ack_sn = rlcP->vr_r; - // HOLES - rlcP->holes[0].valid = 0; - rlcP->nb_missing_pdus = 0; - - working_sn = rlcP->vr_r; - working_sn_index = working_sn % rlcP->recomputed_configured_rx_window_size; - end_sn = rlcP->vr_h; - - while (working_sn != end_sn) { - if ((rlcP->receiver_buffer[working_sn_index])) { - // UPDATE ACK FIELD : - if (rlcP->ack_sn == working_sn) { - rlcP->ack_sn = (working_sn + 1) & SN_12BITS_MASK; - } - - // STOP PREVIOUS HOLE IF ANY - if (rlcP->holes[hole_index].valid) { - hole_index += 1; - rlcP->holes[hole_index].valid = 0; - } - } else { - - // CONTINUE PREVIOUS HOLE IF ANY - if (rlcP->holes[hole_index].valid) { - rlcP->holes[hole_index].length += 1; - rlcP->nb_missing_pdus += 1; - - // START HOLE IF ANY - } else { -#ifdef DEBUG_RLC_AM_FIND_HOLE - msg ("[RLC_AM %p] FOUND HOLE %d START 0x%04x(hex)\n", rlcP, hole_index, working_sn); -#endif - - if (hole_index > 0) { - distance = working_sn - rlcP->holes[hole_index - 1].fsn; - - if (distance & 0x8000) { // < 0 - rlcP->holes[hole_index - 1].dist_to_next = distance + SN_12BITS_MASK + 1; - } else { - rlcP->holes[hole_index - 1].dist_to_next = distance; - } - } - - rlcP->holes[hole_index].valid = 1; - rlcP->holes[hole_index + 1].valid = 0; - rlcP->holes[hole_index].fsn = working_sn; - rlcP->holes[hole_index].length = 1; - rlcP->nb_missing_pdus += 1; - } - } - - working_sn = (working_sn + 1) & SN_12BITS_MASK; - working_sn_index = working_sn % rlcP->recomputed_configured_rx_window_size; - } - - // compute the number of holes - if (rlcP->holes[hole_index].valid) { - rlcP->nb_holes = hole_index; - } else { - if (hole_index > 0) { - rlcP->nb_holes = hole_index - 1; - } else { - rlcP->nb_holes = 0; - } - } -} - -//----------------------------------------------------------------------------- -void -rlc_am_process_status_info (struct rlc_am_entity *rlcP, uint8_t * statusP) -{ - //----------------------------------------------------------------------------- - - uint8_t *byte1; - uint8_t byte_aligned; // 1: quartet starts on bit 7, 0: quartet starts on bit 3 (of a byte) - uint8_t sufi_type; - uint8_t end_process = 0; - int16_t ack_sn = -1; - int16_t first_error_indicated_sn = -1; - int16_t sn_index; - int16_t current_sn; - int16_t current_index; - - byte1 = statusP; - -#ifdef DEBUG_PROCESS_STATUS - display_retransmission_buffer (rlcP); -#endif - - if ((*byte1 & RLC_PIGGY_PDU_TYPE_MASK) == RLC_PIGGY_PDU_TYPE_STATUS) { - sufi_type = *byte1 & 0x0F; - byte_aligned = 0; - - // process all bytes of the PDU - while (!end_process) { - // reset may have been triggered during processing of status, so exit - //if (rlcP->protocol_state == RLC_DATA_TRANSFER_READY_STATE){ - switch (sufi_type) { - - case RLC_AM_SUFI_NO_MORE: - // end of pdu - end_process = 1; - break; - - case RLC_AM_SUFI_WINDOW: - msg ("[RLC_AM %p]PROCESS_STATUS ERROR process_status_info() RLC_AM_SUFI_WINDOW not implemented\n", rlcP); - end_process = 1; - break; - - case RLC_AM_SUFI_ACK: - -#ifdef DEBUG_PROCESS_STATUS - msg ("[RLC_AM %p]PROCESS_STATUS ACK\n", rlcP); -#endif - ack_sn = retransmission_buffer_management_ack (rlcP, byte1, byte_aligned, &first_error_indicated_sn); - -#ifdef DEBUG_PROCESS_STATUS - msg ("[RLC_AM %p]PROCESS_STATUS ACK WAS LSN %d(b10) %4X(b16)\n", rlcP, ack_sn, ack_sn); -#endif - // DISCARD : A discard procedure is terminated in the sender on the reception of a status pdu which contains - // an ACK SUFI indicating VR(R) > SN_MRWlength - rlc_am_received_sufi_ack_check_discard_procedures (rlcP); - - // end of pdu, no NO_MORE sufi; - end_process = 1; -#ifdef DEBUG_PROCESS_STATUS - display_protocol_vars_rlc_am (rlcP); -#endif - break; - - case RLC_AM_SUFI_LIST: - -#ifdef DEBUG_PROCESS_STATUS - msg ("[RLC_AM %p]PROCESS_STATUS LIST\n", rlcP); -#endif - byte1 = retransmission_buffer_management_list (rlcP, byte1, byte_aligned, &first_error_indicated_sn); - - if (byte1 == NULL) { - // error in processing; - end_process = 1; - break; - } - - // byte aligned is not changed for this sufi; - if (!byte_aligned) { - sufi_type = *byte1 & 0X0F; - } else { - sufi_type = (*byte1 & 0xF0) >> 4; - } - - break; - - case RLC_AM_SUFI_BITMAP: - -#ifdef DEBUG_PROCESS_STATUS - msg ("[RLC_AM %p]PROCESS_STATUS BITMAP %p 0x%02X\n", rlcP, byte1, *byte1); -#endif - byte1 = retransmission_buffer_management_bitmap (rlcP, byte1, byte_aligned, &first_error_indicated_sn); - - if (byte1 == NULL) { - // error in processing; - end_process = 1; - break; - } - - // the length of this sufi is always n bytes + 4; - // so invert byte_aligned; - if (byte_aligned) { - byte_aligned = 0; - sufi_type = *byte1 & 0X0F; - } else { - byte_aligned = 1; - sufi_type = (*byte1 & 0xF0) >> 4; - } - - break; - - case RLC_AM_SUFI_RLIST: - msg ("[RLC_AM %p]PROCESS_STATUS ERROR SUFI RLIST NOT IMPLEMENTED\n", rlcP); - end_process = 1; - break; - - case RLC_AM_SUFI_MRW: -#ifdef DEBUG_PROCESS_STATUS - msg ("[RLC_AM %p]PROCESS_STATUS MRW %p 0x%02X\n", rlcP, byte1, *byte1); -#endif - byte1 = retransmission_buffer_management_mrw (rlcP, byte1, &byte_aligned); - - if (byte1 == NULL) { - // error in processing; - end_process = 1; - break; - } - - // the length of this sufi is always n bytes + 4; - // so invert byte_aligned; - if (byte_aligned) { - sufi_type = (*byte1 & 0xF0) >> 4; - } else { - sufi_type = *byte1 & 0X0F; - } - - break; - - case RLC_AM_SUFI_MRW_ACK: -#ifdef DEBUG_PROCESS_STATUS - msg ("[RLC_AM %p]PROCESS_STATUS MRW_ACK %p 0x%02X\n", rlcP, byte1, *byte1); -#endif - byte1 = retransmission_buffer_management_mrw_ack (rlcP, byte1, &byte_aligned); - - if (byte1 == NULL) { - // error in processing; - end_process = 1; - break; - } - - // the length of this sufi is always n bytes + 4; - // so invert byte_aligned; - if (byte_aligned) { - sufi_type = (*byte1 & 0xF0) >> 4; - } else { - sufi_type = *byte1 & 0X0F; - } - - break; - - default: - msg ("[RLC_AM %p]PROCESS_STATUS ERROR SUFI UNKNOWN 0x%02X\n", rlcP, *byte1); - end_process = 1; - } - - /*} else { - return; - } */ - } - - //------------------------- - // CLEAR ALL EVENTS RECEIVED; - //------------------------- - current_sn = rlcP->vt_a; - current_index = rlcP->vt_a % rlcP->recomputed_configured_tx_window_size; - sn_index = rlcP->vt_s % rlcP->recomputed_configured_tx_window_size; - - while (sn_index != current_index) { - if (rlcP->retransmission_buffer[current_index] != NULL) { - - ((struct rlc_am_tx_data_pdu_management *) (rlcP->retransmission_buffer[current_index]->data))->ack = RLC_AM_PDU_ACK_NO_EVENT; - } - - current_sn = (current_sn + 1) & SN_12BITS_MASK; - current_index = current_sn % rlcP->recomputed_configured_tx_window_size; - } - - } else { - msg ("[RLC_AM %p][PROCESS_STATUS] ERROR process_piggybacked_status_info() PDU type field is not STATUS\n", rlcP); - } - -#ifdef DEBUG_PROCESS_STATUS - display_retransmission_buffer (rlcP); -#endif -} - -//----------------------------------------------------------------------------- -mem_block_t * -rlc_am_create_status_pdu_mrw_ack (struct rlc_am_entity *rlcP, uint8_t nP, uint16_t sn_ackP) -{ - //----------------------------------------------------------------------------- - mem_block_t *le; - struct rlc_am_status_header *pdu; - uint8_t *p8; - -#ifdef DEBUG_STATUS - msg ("[RLC_AM %p][STATUS] rlc_am_mrw_send_ack(N=%d, sn_ack=0x%04X)\n", rlcP, nP, sn_ackP); -#endif - le = get_free_mem_block (rlcP->pdu_size + sizeof (struct rlc_am_tx_control_pdu_allocation) + GUARD_CRC_LIH_SIZE); - - if (le == NULL) { - msg ("[MEM_MNGT][ERROR] rlc_am_mrw_send_ack() no free blocks\n"); - return NULL; - } else { - ((struct rlc_am_tx_control_pdu_management *) (le->data))->rlc_tb_type = RLC_AM_STATUS_PDU_TYPE; - pdu = (struct rlc_am_status_header *) (&le->data[sizeof (struct rlc_am_tx_control_pdu_allocation)]); - pdu->byte1 = RLC_PDU_TYPE_STATUS; - p8 = &(pdu->byte1); - *p8 = *p8 | RLC_AM_SUFI_MRW_ACK; - p8 = p8 + 1; - *p8 = (nP << 4) | (sn_ackP >> 8); - p8 = p8 + 1; - *p8 = sn_ackP; - p8 = p8 + 1; - *p8 = RLC_AM_SUFI_NO_MORE << 4; - return le; - } -} diff --git a/openair2/LAYER2/RLC/AM/rlc_am_status_proto_extern.h b/openair2/LAYER2/RLC/AM/rlc_am_status_proto_extern.h deleted file mode 100755 index e5c0526b30c59b59912d90b07b0ece7592321d6c..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_status_proto_extern.h +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_status_proto_extern.h - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - - ***************************************************************************/ -# ifndef __RLC_AM_STATUS_PROTO_EXTERN_H__ -# define __RLC_AM_STATUS_PROTO_EXTERN_H__ -//----------------------------------------------------------------------------- -# include "rlc_am_entity.h" -# include "rlc_am_structs.h" -# include "rlc_am_constants.h" -# include "mem_block.h" -//----------------------------------------------------------------------------- -extern int rlc_am_send_status (struct rlc_am_entity *rlcP); -extern void rlc_am_process_status_info (struct rlc_am_entity *rlcP, uint8_t * statusP); -extern mem_block_t *rlc_am_create_status_pdu_mrw_ack (struct rlc_am_entity *rlcP, uint8_t nP, uint16_t sn_ackP); -# endif diff --git a/openair2/LAYER2/RLC/AM/rlc_am_structs.h b/openair2/LAYER2/RLC/AM/rlc_am_structs.h deleted file mode 100755 index 8a21b324b12a3159fc8e9370dc910a3885c80843..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_structs.h +++ /dev/null @@ -1,222 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_structs.h - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - ***************************************************************************/ -# ifndef __RLC_AM_STRUCTS_H__ -# define __RLC_AM_STRUCTS_H__ - -# include "platform_types.h" -# include "platform_constants.h" -# include "list.h" -# include "mem_block.h" -# include "rlc_am_constants.h" -//#ifdef USER_MODE -# include "mac_rlc_primitives.h" -//#endif //USER_MODE -# include "mac_primitives.h" -# include "rlc_primitives.h" -//----------------------------------------------------------------------------- -// SDU MANAGEMENT -//----------------------------------------------------------------------------- -struct rlc_am_tx_sdu_management { - uint8_t *first_byte; // payload - int32_t sdu_creation_time; - uint32_t mui; // mui may be used only by radio access bearers - uint16_t sdu_remaining_size; - uint16_t sdu_segmented_size; - uint16_t sdu_size; - int16_t pdus_index[42]; // sn of pdus (is an array) - uint16_t last_pdu_sn; - uint8_t nb_pdus; // number of pdus were this sdu was segmented - uint8_t nb_pdus_internal_use; // count the number of pdus transmitted to lower layers (used in mux procedure) - uint8_t nb_pdus_ack; // counter used for confirm and discard MaxDAT - uint8_t nb_pdus_time; // counter used for timer based discard - - uint8_t confirm; // confirm may be used only by signalling radio bearers - - int8_t li_index_for_discard; // indicates the li index in the last pdu of the sdu, marking the end of the sdu - uint8_t discarded; - uint8_t segmented; // != 0 if segmentation running or achieved - uint8_t no_new_sdu_segmented_in_last_pdu; -}; -//----------------------------------------------------------------------------- -// SDU DISCARD -//----------------------------------------------------------------------------- -struct rlc_am_discard_procedure { - // list of sdu discarded involved in this procedure - list_t sdu_list; // index of sdu (index in rlc_am_entity.input_sdus[]) - uint8_t nb_sdu; - mem_block_t *control_pdu; - uint16_t last_pdu_sn; // for update of vt_s - uint8_t length; - uint8_t nlength; - uint8_t running; -}; -//----------------------------------------------------------------------------- -// DATA PDU -//----------------------------------------------------------------------------- -struct rlc_am_rx_pdu_management { - uint8_t *first_byte; - uint16_t sn; - uint8_t piggybacked_processed; // the piggybacked info if any of the pdu has already been processed. -}; - -struct rlc_am_tx_data_pdu_management { - mem_block_t *copy; //pointer on pdu queued in retransmission_buffer_to_send in order - // not to insert the same pdu to retransmit twice, also to avoid the transmission of the pdu if acknowledged - // but previously was queued for retransmission in retransmission_buffer_to_send but not sent because of - // limited number of pdu delivered by TTI. - uint8_t *first_byte; // pointer on the pdu including header, LIs; - uint8_t *payload; // pointer on the data field of the pdu; - int16_t sdu[15]; // index of sdu having segments in this pdu (index in rlc_am_entity.input_sdus[]) - uint16_t padding_size; // size of padding area if any in a data pdu(for piggybacking) - uint16_t data_size; - uint16_t sn; - - - uint8_t nb_sdu; // number of sdu having segments in this pdu - uint8_t vt_dat; // This state variable counts the number of times a PDU has been transmitted; - // there is one VT(DAT) for each PDU and it is incremented each time the PDU is transmitted; - int8_t ack; // used when pdu is in retransmission buffer; - // values are RLC_PDU_ACK_NO_EVENT, RLC_PDU_ACK_EVENT, RLC_PDU_NACK_EVENT - uint8_t last_pdu_of_sdu; // nb of sdus ending in this pdu (for polling trigger) - - uint16_t rlc_tb_type; // mac will return this value with the tx status - uint8_t dummy[MAC_HEADER_MAX_SIZE]; // reserve area for mac header !!! always the last declaration in this struct !!! -}; - -struct rlc_am_tx_control_pdu_management { - uint16_t rlc_tb_type; // mac will return this value with the tx status - uint8_t dummy[MAC_HEADER_MAX_SIZE]; // reserve area for mac header !!! always the last declaration in this struct !!! -}; - -//----------------------------------------------------------------------------- -// HEADERS -//----------------------------------------------------------------------------- -struct rlc_am_pdu_header { - uint8_t byte1; - uint8_t byte2; - uint8_t li_data_7[1]; -}; - -struct rlc_am_reset_header { - uint8_t byte1; - uint8_t hfni[3]; // is coded on 20 most significant bits of 24 bits -}; - -struct rlc_am_status_header { - uint8_t byte1; - uint8_t suffi[1]; // next suffi(s) -}; -//----------------------------------------------------------------------------- -// interlayers optimizations -//----------------------------------------------------------------------------- -struct rlc_am_tx_data_pdu_allocation { - union { - struct rlc_am_tx_data_pdu_management rlc_am_tx_pdu_mngmnt; - struct mac_tb_req tb_req; - struct mac_tx_tb_management tb_mngt; -# ifdef BYPASS_L1 - struct rlc_am_rx_pdu_management dummy; - struct mac_tb_ind dummy2; - struct mac_rx_tb_management dummy3; - struct rlc_indication dummy4; -# endif - } dummy; -}; - -struct rlc_am_tx_control_pdu_allocation { - union { - struct mac_tb_req tb_req; - struct mac_tx_tb_management tb_mngt; - struct rlc_am_tx_control_pdu_management rlc_am_tx_pdu_mngmnt; -# ifdef BYPASS_L1 - struct mac_tb_ind dummy2; - struct mac_rx_tb_management dummy3; - struct rlc_indication dummy4; -# endif - } dummy; -}; - -struct rlc_am_data_req_alloc { // alloc enought bytes for sdu mngt also - union { - struct rlc_am_data_req dummy1; - struct rlc_am_tx_sdu_management dummy2; - } dummy; -}; -//----------------------------------------------------------------------------- -// MISC -//----------------------------------------------------------------------------- -struct sufi_to_insert_in_status { - uint16_t sn; - uint8_t length; // in quartets, sufi invalid if length is zero - uint8_t type; // ACK, BITMAP, LIST, etc - uint8_t sufi[SUFI_MAX_SIZE]; -}; - -struct sufi_bitmap { - uint16_t fsn; - uint8_t valid; - uint8_t length; - uint8_t mask; - uint8_t bitmap[16]; -}; - -struct pair { - uint16_t sn; - uint8_t valid; - uint8_t length; -}; - -struct sufi_list { - struct pair pairs[15]; - uint8_t valid; - uint8_t length; -}; - -struct sufi_ack { - uint16_t lsn; - uint8_t vr_r_modified; // generate ack with vr_r value; - uint8_t ack_other_vr_r; // generate ack with lsn value; -}; -//----------------------------------------------------------------------------- -// STATUS GENERATION -//----------------------------------------------------------------------------- -struct rlc_am_hole { - uint16_t valid; - uint16_t fsn; - uint16_t length; - uint16_t dist_to_next; //count in sn -}; -# endif diff --git a/openair2/LAYER2/RLC/AM/rlc_am_timers.c b/openair2/LAYER2/RLC/AM/rlc_am_timers.c deleted file mode 100755 index 776ba8ae46655f234aa4932c0f0aae491be67bf7..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_timers.c +++ /dev/null @@ -1,199 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_timers.c - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - ***************************************************************************/ -#include "rtos_header.h" -#include "platform_types.h" -//----------------------------------------------------------------------------- -#include "rlc_am_entity.h" -#include "rlc_am_constants.h" -#include "rlc_am_structs.h" -#include "rlc_am_util_proto_extern.h" -#include "umts_timer_proto_extern.h" -/* -void rlc_am_timer_epc_notify_time_out (struct rlc_am_entity *rlcP, void *arg_not_usedP); -void rlc_am_timer_epc_fsm (struct rlc_am_entity *rlcP, uint8_t eventP); -//----------------------------------------------------------------------------- -void -rlc_am_timer_epc_notify_time_out (struct rlc_am_entity *rlcP, void *arg_not_usedP) -{ -//----------------------------------------------------------------------------- - rlc_am_timer_epc_fsm (rlcP, TIMER_EPC_TIMER_TIMED_OUT_EVENT); -} - -//----------------------------------------------------------------------------- -void -rlc_am_timer_epc_fsm (struct rlc_am_entity *rlcP, uint8_t eventP) -{ -//----------------------------------------------------------------------------- - // from 25.322 V4.3.0 - // The Estimated PDU Counter (EPC) is only applicable for RLC entities operating - // in acknowledged mode. The EPC is a mechanism configured by upper layers used - // for scheduling the retransmission of status reports in the Receiver. With this - // mechanism, the Receiver will send a new status report in which it requests for - // AMD PDUs not yet received. The time between two subsequent status report - // retransmissions is not fixed, but it is controlled by both the timer Timer_EPC - // and the state variable VR(EP), which adapt this time to the round trip delay - // and the current bit rate, indicated in the TFI, in order to minimise the delay - // of the status report retransmission. - // - // When a status report is triggered by some mechanisms and it is submitted to lower - // layer (in UTRAN) or the successful or unsuccessful transmission of it is indicated - // by lower layer (in UE) <<SEE CODE "Ref1">> to request for retransmitting one or more missing AMD PDUs, - // the variable VR(EP) is set equal to the number of requested AMD PDUs. At least - // one requested AMD PDU is needed to activate the EPC mechanism. The variable VR(EP) - // is a counter, which is decremented every transmission time interval with the - // estimated number of AMD PDUs that should have been received during that - // transmission time interval on the corresponding logical channel. - // - // The timer Timer_EPC controls the maximum time that the variable VR(EP) needs to - // wait before it will start counting down. This timer starts immediately after a - // transmission of a retransmission request from the Receiver (when the first - // STATUS PDU of the status report is submitted to lower layer (in UTRAN) or the - // successful or unsuccessful transmission of it is indicated by lower layer(in UE)). - // The initial value of the timer Timer_EPC is configured by upper layers. It typically - // depends on the roundtrip delay, which consists of the propagation delay, processing - // time in the transmitter and Receiver and the frame structure. This timer can also - // be implemented as a counter, which counts the number of 10 ms radio frames that - // could be expected to elapse before the first requested AMD PDU is received. - // - // If not all of these requested AMD PDUs have been received correctly when VR(EP) - // is equal to zero, a new status report will be transmitted and the EPC mechanism - // will be reset accordingly. The timer Timer_EPC will be started once more when the - // first STATUS PDU of the status report is submitted to lower layer (in UTRAN) or the - // successful or unsuccessful transmission of it is indicated by lower layer (in UE). - // If all of the requested AMD PDUs have been received correctly, the EPC mechanism ends. - - switch (rlcP->epc_state) { - - //-------------------------------------------- - case TIMER_EPC_STATE_IDLE: - //-------------------------------------------- - rlcP->epc_counting_down = 0; - switch (eventP) { - // Ref1 - case TIMER_EPC_PDU_STATUS_SUBMITTED_LOWER_LAYER_EVENT: // for RG - case TIMER_EPC_PDU_STATUS_TRANSMITED_EVENT: // for UE - rlcP->vr_ep = rlcP->epc_nb_missing_pdus; - rlcP->epc_old_vr_h = rlcP->vr_h; - rlcP->epc_old_vr_r = rlcP->vr_r; - - rlcP->epc_state = TIMER_EPC_STATE_TIMER_ARMED; - rlcP->timer_epc = umts_add_timer_list_up (&rlcP->rlc_am_timer_list, rlc_am_timer_epc_notify_time_out, rlcP, rlcP->discard_procedures.head, NULL, *rlcP->frame_tick_milliseconds); -#ifdef DEBUG_RLC_AM_TIMER_EPC_FSM - msg ("[RLC_AM %p][TIMER_EPC_FSM] TIMER_EPC_STATE_IDLE -> TIMER_EPC_STATE_TIMER_ARMED\n", rlcP); -#endif - - return; - break; - - default: -#ifdef DEBUG_RLC_AM_TIMER_EPC_FSM - msg ("[RLC_AM %p][TIMER_EPC_FSM] TIMER_EPC_STATE_IDLE EVENT %02X hex NOT EXPECTED\n", rlcP, eventP); -#endif - return; - } - break; - - - //-------------------------------------------- - case TIMER_EPC_STATE_TIMER_ARMED: - //-------------------------------------------- - switch (eventP) { - // Ref1 - case TIMER_EPC_PDU_STATUS_TRANSMITED_EVENT: - return; - break; - - case TIMER_EPC_TIMER_TIMED_OUT_EVENT: - rlcP->epc_counting_down = 1; - rlcP->timer_epc = NULL; - rlcP->epc_state = TIMER_EPC_STATE_TIMED_OUT; - -#ifdef DEBUG_RLC_AM_TIMER_EPC_FSM - msg ("[RLC_AM %p][TIMER_EPC_FSM] TIMER_EPC_STATE_TIMER_ARMED -> TIMER_EPC_STATE_TIMED_OUT\n", rlcP); -#endif - return; - break; - - default: -#ifdef DEBUG_RLC_AM_TIMER_EPC_FSM - msg ("[RLC_AM %p][TIMER_EPC_FSM] TIMER_EPC_STATE_TIMER_ARMED EVENT %02X hex NOT EXPECTED\n", rlcP, eventP); -#endif - return; - } - break; - - //-------------------------------------------- - case TIMER_EPC_STATE_TIMED_OUT: - //-------------------------------------------- - switch (eventP) { - - case TIMER_EPC_VR_EP_EQUAL_ZERO_EVENT: - rlcP->epc_counting_down = 0; - rlcP->epc_state = TIMER_EPC_STATE_IDLE; - - // return 1 if sn1 > sn2 - // return 0 if sn1 = sn2 - // return -1 if sn1 < sn2 - if (rlc_am_comp_sn (rlcP, rlcP->epc_old_vr_r, rlcP->epc_old_vr_h, rlcP->vr_r) > 0) { - // not all missing pdus have been received - // so generate a new status report - rlcP->send_status_pdu_requested = 1; -#ifdef DEBUG_RLC_AM_TIMER_EPC_FSM - msg ("[RLC_AM %p][TIMER_EPC_FSM] TIMER_EPC_STATE_TIMED_OUT -> TIMER_EPC_STATE_IDLE GENERATION OF STATUS REQUESTED\n", rlcP); -#endif - } -#ifdef DEBUG_RLC_AM_TIMER_EPC_FSM - else { - msg ("[RLC_AM %p][TIMER_EPC_FSM] TIMER_EPC_STATE_TIMED_OUT -> TIMER_EPC_STATE_IDLE\n", rlcP); - } -#endif - return; - break; - - default: -#ifdef DEBUG_RLC_AM_TIMER_EPC_FSM - msg ("[RLC_AM %p][TIMER_EPC_FSM] TIMER_EPC_STATE_TIMED_OUT EVENT %02X hex NOT EXPECTED\n", rlcP, eventP); -#endif - return; - } - break; - - default:; - } -} -*/ diff --git a/openair2/LAYER2/RLC/AM/rlc_am_timers_proto_extern.h b/openair2/LAYER2/RLC/AM/rlc_am_timers_proto_extern.h deleted file mode 100755 index 85c44dfafeb8dc2ce54b462a8d715e683ef99430..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_timers_proto_extern.h +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_timers_proto_extern.h - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - ***************************************************************************/ -# ifndef __RLC_AM_TIMERS_H__ -# define __RLC_AM_RIMERS_H__ -# include "rlc_am_entity.h" -# include "platform_types.h" - -extern void rlc_am_timer_epc_notify_time_out (struct rlc_am_entity *rlcP, void *arg_not_usedP); -extern void rlc_am_timer_epc_fsm (struct rlc_am_entity *rlcP, uint8_t eventP); -# endif diff --git a/openair2/LAYER2/RLC/AM/rlc_am_util.c b/openair2/LAYER2/RLC/AM/rlc_am_util.c deleted file mode 100755 index 129fb075ad337db48834cf0309602662fa4386de..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_util.c +++ /dev/null @@ -1,486 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_discard_rx.c - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - ***************************************************************************/ -#include "rtos_header.h" -#include "platform_types.h" -//----------------------------------------------------------------------------- -#include "rlc_primitives.h" -#include "rlc_am_entity.h" -#include "rlc_am_structs.h" -#include "mem_block.h" -//----------------------------------------------------------------------------- -inline int rlc_am_comp_sn (struct rlc_am_entity* rlcP, uint16_t low_boundaryP, uint16_t sn1P, uint16_t sn2P); -void adjust_vr_r_mr (struct rlc_am_entity* rlcP); -void adjust_vt_a_ms (struct rlc_am_entity* rlcP); -void display_protocol_vars_rlc_am (struct rlc_am_entity* rlcP); -void display_retransmission_buffer (struct rlc_am_entity* rlcP); -void display_receiver_buffer (struct rlc_am_entity* rlcP); -void rlc_am_check_retransmission_buffer (struct rlc_am_entity* rlcP, uint8_t* messageP); -void rlc_am_check_receiver_buffer (struct rlc_am_entity* rlcP, uint8_t* messageP); -void rlc_am_display_data_pdu7 (mem_block_t* pduP); -//----------------------------------------------------------------------------- -#ifdef DEBUG_RLC_AM_CONFIRM -//----------------------------------------------------------------------------- -void -debug_rlc_am_confirm (struct rlc_am_entity* rlcP, mem_block_t* confP) -{ - //----------------------------------------------------------------------------- - msg ("[RLC_AM][RB %d] CONFIRM SDU MUI %d\n", rlcP->rb_id, ((struct rlc_output_primitive*) (confP->data))->primitive.conf.mui); - free_mem_block_t (confP); -} -#endif /* DEBUG_RLC_AM_CONFIRM */ - -// return 1 if sn1 > sn2 -// return 0 if sn1 = sn2 -// return -1 if sn1 < sn2 -//----------------------------------------------------------------------------- -inline int -rlc_am_comp_sn (struct rlc_am_entity* rlcP, uint16_t low_boundaryP, uint16_t sn1P, uint16_t sn2P) -{ - //----------------------------------------------------------------------------- - // we require that sn are in tx window, if they are not we consider that they are always - // before low_boundaryP (one loop over the max sn 0x0FFF), never above the boundary - uint16_t bound = (low_boundaryP + rlcP->configured_tx_window_size - 1) & SN_12BITS_MASK; - - if (sn1P == sn2P) { - return 0; - } - - if (low_boundaryP < bound) { - if ((sn1P >= low_boundaryP) && (sn1P <= bound)) { - if ((sn2P >= low_boundaryP) && (sn2P <= bound)) { - if (sn1P > sn2P) { - return 1; - - } else { - return -1; - } - - } else { // not in tx window - return 1; - } - - } else { // not in tx window - if ((sn2P >= low_boundaryP) && (sn2P <= bound)) { - return -1; - - } else { - if ((sn1P > sn2P) && (sn1P <= low_boundaryP)) { - return 1; - - } else if ((sn2P > sn1P) && (sn2P <= low_boundaryP)) { - return -1; - - } else if ((sn1P > sn2P) && (sn1P > bound)) { - return -1; - - } else { - return 1; - } - } - } - - } else { - if (sn1P >= low_boundaryP) { - if (sn2P <= bound) { - return -1; - - } else if ((sn2P >= low_boundaryP)) { - if (sn1P > sn2P) { - return 1; - - } else { - return -1; - } - - } else { // not in tx window - return -1; - } - - } else if (sn1P <= bound) { - if (sn2P > bound) { - return 1; - - } else { - if (sn1P > sn2P) { - return 1; - - } else { - return -1; - } - } - - } else { // bound < sn1< vt_a - if (sn2P >= low_boundaryP) { - return -1; - - } else if (sn2P <= bound) { - return -1; - - } else { - if (sn1P > sn2P) { - return 1; - - } else { - return -1; - } - } - } - } -} - -//----------------------------------------------------------------------------- -void -adjust_vt_a_ms (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - uint16_t vt_a_index, vt_s_index; - vt_a_index = rlcP->vt_a % rlcP->recomputed_configured_tx_window_size; - vt_s_index = rlcP->vt_s % rlcP->recomputed_configured_tx_window_size; - - while ((rlcP->retransmission_buffer[vt_a_index] == NULL) && (vt_a_index != vt_s_index)) { - rlcP->vt_a = (rlcP->vt_a + 1) & SN_12BITS_MASK; - vt_a_index = rlcP->vt_a % rlcP->recomputed_configured_tx_window_size; - } - - rlcP->vt_ms = (rlcP->vt_a + rlcP->vt_ws - 1) & SN_12BITS_MASK; -} - -//----------------------------------------------------------------------------- -void -adjust_vr_r_mr (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - uint16_t vr_r_index, vr_h_index; - vr_r_index = rlcP->vr_r % rlcP->recomputed_configured_rx_window_size; - vr_h_index = rlcP->vr_h % rlcP->recomputed_configured_rx_window_size; - - while ((rlcP->receiver_buffer[vr_r_index] != NULL) && (vr_r_index != vr_h_index)) { - rlcP->vr_r = (rlcP->vr_r + 1) & SN_12BITS_MASK; - vr_r_index = rlcP->vr_r % rlcP->recomputed_configured_rx_window_size; - } - - rlcP->ack.vr_r_modified = 1; -#ifdef DEBUG_RECEIVER_BUFFER - msg ("[RLC_AM][RB %d][RECEIVER_BUFFER] ADJUST VR(R)->0x%04X VR(H)=0x%04X\n", rlcP->rb_id, rlcP->vr_r, rlcP->vr_h); -#endif - rlcP->vr_mr = (rlcP->vr_r + rlcP->configured_rx_window_size - 1) & SN_12BITS_MASK; -} - -//----------------------------------------------------------------------------- -void -display_protocol_vars_rlc_am (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - msg ("[RLC_AM][RB %d] VT(A) 0x%04X VT(S) 0x%04X VT(MS) 0x%04X VT(PDU) 0x%04X VT(SDU) 0x%04X VR(R) 0x%04X VR(H) 0x%04X VR(MR) 0x%04X\n", - rlcP->rb_id, rlcP->vt_a, rlcP->vt_s, rlcP->vt_ms, rlcP->vt_pdu, rlcP->vt_sdu, rlcP->vr_r, rlcP->vr_h, rlcP->vr_mr); -} - -//----------------------------------------------------------------------------- -void -display_retransmission_buffer (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - uint16_t working_sn, working_sn_index; - uint16_t end_sn, end_sn_index; - working_sn = rlcP->vt_a; - working_sn_index = working_sn % rlcP->recomputed_configured_tx_window_size; - end_sn = (rlcP->vt_a + rlcP->recomputed_configured_tx_window_size - 1) & SN_12BITS_MASK; - end_sn_index = end_sn % rlcP->recomputed_configured_tx_window_size; - msg ("-------------------------------------------\nRetrans Buf rlc %p: VT(A) 0x%04X VT(S) 0x%04X XXX = sn based on index, (XXX) = sn read from pdu\n", rlcP, - rlcP->vt_a, rlcP->vt_s); - - while (working_sn_index != end_sn_index) { - if (rlcP->retransmission_buffer[working_sn_index] != NULL) { - msg ("%03X(%03X).", working_sn, ((struct rlc_am_tx_data_pdu_management*) (rlcP->retransmission_buffer[working_sn_index]->data))->sn); - - } else { - msg ("_."); - } - - if ((working_sn_index % 32) == 0) { - msg ("\n"); - } - - working_sn = (working_sn + 1) & SN_12BITS_MASK; - working_sn_index = working_sn % rlcP->recomputed_configured_tx_window_size; - } - - msg ("\n------------------------------------------\n"); -} - -//----------------------------------------------------------------------------- -void -display_receiver_buffer (struct rlc_am_entity* rlcP) -{ - //----------------------------------------------------------------------------- - uint16_t working_sn, working_sn_index; - uint16_t end_sn, end_sn_index; - working_sn = rlcP->vr_r; - working_sn_index = working_sn % rlcP->recomputed_configured_rx_window_size; - end_sn = rlcP->vr_mr; - end_sn_index = end_sn % rlcP->recomputed_configured_rx_window_size; - msg ("-------------------------------\nRec Buf rlc %p VR(R) 0x%04X: ", rlcP, rlcP->vr_r); - - while (working_sn_index != end_sn_index) { - if (rlcP->receiver_buffer[working_sn_index] != NULL) { - msg ("%03X(%03X)", working_sn, ((struct rlc_am_rx_pdu_management*) (rlcP->receiver_buffer[working_sn_index]->data))->sn); - - } else { - msg ("_."); - } - - if ((working_sn_index % 32) == 0) { - msg ("\n"); - } - - working_sn = (working_sn + 1) & SN_12BITS_MASK; - working_sn_index = working_sn % rlcP->recomputed_configured_rx_window_size; - } - - msg ("\n--------------------------------------\n"); -} - -//----------------------------------------------------------------------------- -void -rlc_am_check_retransmission_buffer (struct rlc_am_entity* rlcP, uint8_t* messageP) -{ - //----------------------------------------------------------------------------- - int error_found = 0; - uint16_t working_sn, working_sn_index; - uint16_t end_sn, end_sn_index; - //--------------------------------------------- - // check if pdu remaining outside the window - //--------------------------------------------- - working_sn = rlcP->vt_s; - working_sn_index = working_sn % rlcP->recomputed_configured_tx_window_size; - end_sn = rlcP->vt_a; - end_sn_index = end_sn % rlcP->recomputed_configured_tx_window_size; - - while (working_sn_index != end_sn_index) { - if (rlcP->retransmission_buffer[working_sn_index] != NULL) { - msg ("[RLC_AM][RB %d] CHECK RETRANSMISSION BUFFER ERROR %s : REMAINING PDU INDEX %d=0x%04X\n", rlcP->rb_id, messageP, working_sn_index, working_sn_index); - rlc_am_display_data_pdu7 (rlcP->retransmission_buffer[working_sn_index]); - error_found = 1; - } - - working_sn = (working_sn + 1) & SN_12BITS_MASK; - working_sn_index = working_sn % rlcP->recomputed_configured_tx_window_size; - } - - //--------------------------------------------- - // check if pdu remaining inside the window have the correct value for ack field - //--------------------------------------------- - end_sn = rlcP->vt_s; - end_sn_index = end_sn % rlcP->recomputed_configured_tx_window_size; - working_sn = rlcP->vt_a; - working_sn_index = working_sn % rlcP->recomputed_configured_tx_window_size; - - while (working_sn_index != end_sn_index) { - if (rlcP->retransmission_buffer[working_sn_index] != NULL) { - if (((struct rlc_am_tx_data_pdu_management*) (rlcP->retransmission_buffer[working_sn_index]->data))->ack != RLC_AM_PDU_ACK_NO_EVENT) { - msg ("[RLC_AM][RB %d] CHECK RETRANSMISSION BUFFER ERROR %s EVENT (%d) IN PDU SN 0x%04X\n", rlcP->rb_id, messageP, - ((struct rlc_am_tx_data_pdu_management*) (rlcP->retransmission_buffer[working_sn_index]->data))->ack, working_sn); - rlc_am_display_data_pdu7 (rlcP->retransmission_buffer[working_sn_index]); - error_found = 1; - } - } - - working_sn = (working_sn + 1) & SN_12BITS_MASK; - working_sn_index = working_sn % rlcP->recomputed_configured_tx_window_size; - } - - if ((error_found)) { - display_protocol_vars_rlc_am (rlcP); - - while (1); - - } else { - msg ("[RLC_AM][RB %d] CHECK RETRANSMISSION BUFFER OK\n", rlcP->rb_id); - } -} - -//----------------------------------------------------------------------------- -void -rlc_am_check_receiver_buffer (struct rlc_am_entity* rlcP, uint8_t* messageP) -{ - //----------------------------------------------------------------------------- - int error_found = 0; - uint16_t working_sn, working_sn_index; - uint16_t end_sn, end_sn_index; - working_sn = rlcP->vr_h; - working_sn_index = working_sn % rlcP->recomputed_configured_tx_window_size; - end_sn = rlcP->vr_r; - end_sn_index = end_sn % rlcP->recomputed_configured_tx_window_size; - - while (working_sn_index != end_sn_index) { - if (rlcP->receiver_buffer[working_sn_index] != NULL) { - msg ("[RLC_AM][RB %d] CHECK RECEIVER BUFFER ERROR %s : REMAINING PDU INDEX %d=0x%04X\n", rlcP->rb_id, messageP, working_sn_index, working_sn_index); - error_found = 1; - } - - working_sn = (working_sn + 1) & SN_12BITS_MASK; - working_sn_index = working_sn % rlcP->recomputed_configured_rx_window_size; - } - - if ((error_found)) { - while (1); - } -} - -//----------------------------------------------------------------------------- -void -rlc_am_display_data_pdu7 (mem_block_t* pduP) -{ - //----------------------------------------------------------------------------- - struct rlc_am_tx_data_pdu_management* pdu_mngt; - struct rlc_am_pdu_header* rlc_header; - int index; - int nb_li = 0; - int li_index = 0; - uint16_t li[32]; - - if ((pduP)) { - pdu_mngt = (struct rlc_am_tx_data_pdu_management*) (pduP->data); - msg ("[RLC_AM] DISPLAY DATA PDU %p SN 0x%04X LAST_PDU_OF_SDU %d\n", pduP, pdu_mngt->sn, pdu_mngt->last_pdu_of_sdu); - msg ("[RLC_AM] DISPLAY DATA PDU HEADER "); - - for (index = 0; index < 10; index++) { - msg ("%02X.", pdu_mngt->first_byte[index]); - } - - msg ("\n"); - //-------------------------------------- - // LINKED SDUs - //-------------------------------------- - msg ("[RLC_AM] DISPLAY DATA PDU CONTAINS SDU(s) INDEX "); - - for (index = 0; index < pdu_mngt->nb_sdu; index++) { - msg ("%d", pdu_mngt->sdu[index]); - } - - msg ("\n"); - //-------------------------------------- - // LENGTH INDICATORS - //-------------------------------------- - rlc_header = (struct rlc_am_pdu_header*) (pdu_mngt->first_byte); - - if ((rlc_header->byte2 & RLC_HE_MASK) != RLC_HE_SUCC_BYTE_CONTAINS_DATA) { - msg ("[RLC_AM] DISPLAY DATA PDU CONTAINS LI(s) "); - nb_li = 0; - - while ((li[nb_li] = (rlc_header->li_data_7[nb_li])) & RLC_E_NEXT_FIELD_IS_LI_E) { - li[nb_li] = li[nb_li] & (~(uint8_t) RLC_E_NEXT_FIELD_IS_LI_E); - nb_li++; - } - - nb_li++; - - while (li_index < nb_li) { - switch (li[li_index]) { - case RLC_LI_LAST_PDU_EXACTLY_FILLED: - msg ("LAST_PDU_EXACTLY_FILLED "); - break; - - case RLC_LI_LAST_PDU_ONE_BYTE_SHORT: - msg ("LAST_PDU_ONE_BYTE_SHORT "); - break; - - case RLC_LI_PDU_PIGGY_BACKED_STATUS: // ignore - msg ("PDU_PIGGY_BACKED_STATUS "); - break; - - case RLC_LI_PDU_PADDING: - msg ("PDU_PADDING "); - break; - - default: // li is length - msg ("LENGTH %d ", li[li_index] >> 1); - } - - li_index++; - } - - } else { - msg ("[RLC_AM] DISPLAY DATA PDU CONTAINS NO LI(s) "); - } - - msg ("\n"); - //-------------------------------------- - // DATA - //-------------------------------------- - msg ("[RLC_AM] DISPLAY DATA PDU CONTENT <PDU>"); - - for (index = 0; index < pdu_mngt->data_size; index++) { - msg ("%02X.", pdu_mngt->payload[index]); - } - - msg ("</PDU>\n"); - - } else { - msg ("[RLC_AM] DISPLAY DATA PDU : IS NULL\n"); - } -} -//----------------------------------------------------------------------------- -void -rlc_am_stat_req (struct rlc_am_entity* rlcP, - unsigned int* tx_pdcp_sdu, - unsigned int* tx_pdcp_sdu_discarded, - unsigned int* tx_retransmit_pdu_unblock, - unsigned int* tx_retransmit_pdu_by_status, - unsigned int* tx_retransmit_pdu, - unsigned int* tx_data_pdu, - unsigned int* tx_control_pdu, - unsigned int* rx_sdu, - unsigned int* rx_error_pdu, - unsigned int* rx_data_pdu, - unsigned int* rx_data_pdu_out_of_window, - unsigned int* rx_control_pdu) -{ - //----------------------------------------------------------------------------- - *tx_pdcp_sdu = rlcP->stat_tx_pdcp_sdu; - *tx_pdcp_sdu_discarded = rlcP->stat_tx_pdcp_sdu_discarded; - *tx_retransmit_pdu_unblock = rlcP->stat_tx_retransmit_pdu_unblock; - *tx_retransmit_pdu_by_status = rlcP->stat_tx_retransmit_pdu_by_status; - *tx_retransmit_pdu = rlcP->stat_tx_retransmit_pdu; - *tx_data_pdu = rlcP->stat_tx_data_pdu; - *tx_control_pdu = rlcP->stat_tx_control_pdu; - *rx_sdu = rlcP->stat_rx_sdu; - *rx_error_pdu = rlcP->stat_rx_error_pdu; - *rx_data_pdu = rlcP->stat_rx_data_pdu; - *rx_data_pdu_out_of_window = rlcP->stat_rx_data_pdu_out_of_window; - *rx_control_pdu = rlcP->stat_rx_control_pdu; -} diff --git a/openair2/LAYER2/RLC/AM/rlc_am_util_proto_extern.h b/openair2/LAYER2/RLC/AM/rlc_am_util_proto_extern.h deleted file mode 100755 index 78a2425be0c77faec8782a627eb81198a796a726..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/RLC/AM/rlc_am_util_proto_extern.h +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*************************************************************************** - rlc_am_util_proto_extern.h - - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - ***************************************************************************/ -# ifndef __RLC_AM_UTIL_PROTO_EXTERN_H__ -# define __RLC_AM_UTIL_PROTO_EXTERN_H__ -//----------------------------------------------------------------------------- -# include "rlc_am_entity.h" -# include "mem_block.h" -//----------------------------------------------------------------------------- -extern void rlc_am_stat_req (struct rlc_am_entity *rlcP, - unsigned int* tx_pdcp_sdu, - unsigned int* tx_pdcp_sdu_discarded, - unsigned int* tx_retransmit_pdu_unblock, - unsigned int* tx_retransmit_pdu_by_status, - unsigned int* tx_retransmit_pdu, - unsigned int* tx_data_pdu, - unsigned int* tx_control_pdu, - unsigned int* rx_sdu, - unsigned int* rx_error_pdu, - unsigned int* rx_data_pdu, - unsigned int* rx_data_pdu_out_of_window, - unsigned int* rx_control_pdu); -extern int rlc_am_comp_sn (struct rlc_am_entity *rlcP, uint16_t low_boundaryP, uint16_t sn1P, uint16_t sn2P); -extern void adjust_vr_r_mr (struct rlc_am_entity *rlcP); -extern void adjust_vt_a_ms (struct rlc_am_entity *rlcP); -extern void display_protocol_vars_rlc_am (struct rlc_am_entity *rlcP); -extern void display_retransmission_buffer (struct rlc_am_entity *rlcP); -extern void display_receiver_buffer (struct rlc_am_entity *rlcP); -extern void rlc_am_check_retransmission_buffer (struct rlc_am_entity *rlcP, uint8_t * messageP); -extern void rlc_am_check_receiver_buffer (struct rlc_am_entity *rlcP, uint8_t * messageP); -extern void rlc_am_display_data_pdu7 (mem_block_t * pduP); -# ifdef DEBUG_RLC_AM_CONFIRM -void debug_rlc_am_confirm (struct rlc_am_entity *rlcP, uint32_t muiP); -# endif -# endif