commit 7c176870b35cb55deea280f0a5343b096844acd9 Author: Tzafrir Cohen Date: Fri Aug 14 11:05:47 2015 +0200 Imported Upstream version 2.10.2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eec9c01 --- /dev/null +++ b/.gitignore @@ -0,0 +1,51 @@ +*.o +.*.o.d +.*.lo.d +*.asciidoc +*.html +build_tools/menuselect-deps +autoconfig.h +config.log +config.status +dahdi_cfg +dahdi_diag +dahdi_maint +dahdi_monitor +dahdi_scan +dahdi_speed +dahdi_test +dahdi_tool +fxotune +fxstest +genconf_parameters.sample +hdlcgen +hdlcstress +hdlctest +hdlcverify +libtonezone.a +libtonezone.so +makeopts +patgen +patlooptest +pattest +sethdlc +timertest +tonezone.lo +tonezones.txt +version.c +xpp/.depend +xpp/.octasic.depend +xpp/.perlcheck +xpp/astribank_allow +xpp/astribank_hexload +xpp/astribank_is_starting +xpp/astribank_tool +xpp/dahdi_genconf.8 +xpp/dahdi_hardware.8 +xpp/dahdi_registration.8 +xpp/lsdahdi.8 +xpp/test_parse +xpp/twinstar.8 +xpp/xpp_blink.8 +xpp/xpp_sync.8 +zonedata.lo diff --git a/.version b/.version new file mode 100644 index 0000000..c6436a8 --- /dev/null +++ b/.version @@ -0,0 +1 @@ +2.10.2 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a52b16e --- /dev/null +++ b/LICENSE @@ -0,0 +1,341 @@ + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +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 +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE 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. + + 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 +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This 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 Library General +Public License instead of this License. diff --git a/LICENSE.LGPL b/LICENSE.LGPL new file mode 100644 index 0000000..1f7c8cc --- /dev/null +++ b/LICENSE.LGPL @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +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 this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +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 +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..69741e6 --- /dev/null +++ b/Makefile @@ -0,0 +1,390 @@ +# +# Makefile for DAHDI tools +# +# Copyright (C) 2001-2010 Digium, Inc. +# +# + +ifeq ($(strip $(foreach var,clean distclean dist-clean update,$(findstring $(var),$(MAKECMDGOALS)))),) +endif + +ifeq ($(strip $(foreach var,clean distclean dist-clean update,$(findstring $(var),$(MAKECMDGOALS)))),) + ifneq ($(wildcard makeopts),) + include makeopts + endif +endif + +SUBDIRS_UTILS_ALL:= ppp +SUBDIRS_UTILS := xpp + +OPTFLAGS=-O2 +CFLAGS+=-I. $(OPTFLAGS) -g -fPIC -Wall -DBUILDING_TONEZONE #-DTONEZONE_DRIVER +ifneq (,$(findstring ppc,$(UNAME_M))) +CFLAGS+=-fsigned-char +endif +ifneq (,$(findstring x86_64,$(UNAME_M))) +CFLAGS+=-m64 +endif + +ifeq ($(DAHDI_DEVMODE),yes) + CFLAGS+=-Werror -Wunused -Wundef $(DAHDI_DECLARATION_AFTER_STATEMENT) -Wmissing-format-attribute -Wformat-security #-Wformat=2 +endif + +ROOT_PREFIX= + +# extra cflags to build dependencies. Recursively expanded. +MAKE_DEPS= -MD -MT $@ -MF .$(subst /,_,$@).d -MP + +CFLAGS+=$(DAHDI_INCLUDE) + +CHKCONFIG := $(wildcard /sbin/chkconfig) +UPDATE_RCD := $(wildcard /usr/sbin/update-rc.d) +ifeq (,$(DESTDIR)) + ifneq (,$(CHKCONFIG)) + ADD_INITD := $(CHKCONFIG) --add dahdi + else + ifneq (,$(UPDATE_RCD)) + ADD_INITD := $(UPDATE_RCD) dahdi defaults 15 30 + endif + endif +endif + +INITRD_DIR := $(firstword $(wildcard $(DESTDIR)/etc/rc.d/init.d $(DESTDIR)/etc/init.d)) +ifneq (,$(INITRD_DIR)) + INIT_TARGET := $(INITRD_DIR)/dahdi + COPY_INITD := install -D dahdi.init $(INIT_TARGET) +endif + +RCCONF_FILE = /etc/dahdi/init.conf +MODULES_FILE = /etc/dahdi/modules +GENCONF_FILE = /etc/dahdi/genconf_parameters +MODPROBE_FILE = /etc/modprobe.d/dahdi.conf +BLACKLIST_FILE = /etc/modprobe.d/dahdi.blacklist.conf +BASH_COMP_DIR = /etc/bash_completion.d +BASH_COMP_FILE = $(BASH_COMP_DIR)/dahdi + +NETSCR_DIR := $(firstword $(wildcard $(DESTDIR)/etc/sysconfig/network-scripts )) +ifneq (,$(NETSCR_DIR)) + NETSCR_TARGET := $(NETSCR_DIR)/ifup-hdlc + COPY_NETSCR := install -D ifup-hdlc $(NETSCR_TARGET) +endif + +TOOLSVERSION=$(shell build_tools/make_version . dahdi/tools) + +LTZ_A:=libtonezone.a +LTZ_A_OBJS:=zonedata.o tonezone.o version.o +LTZ_SO:=libtonezone.so +LTZ_SO_OBJS:=zonedata.lo tonezone.lo version.o +LTZ_SO_MAJOR_VER:=2 +LTZ_SO_MINOR_VER:=0 + +# sbindir, libdir, includedir and mandir are defined in makeopts +# (from configure). +BIN_DIR:=$(sbindir) +LIB_DIR:=$(libdir) +INC_DIR:=$(includedir)/dahdi +MAN_DIR:=$(mandir)/man8 +DATA_DIR:=${datadir}/dahdi +CONFIG_DIR:=$(sysconfdir)/dahdi +CONFIG_FILE:=$(CONFIG_DIR)/system.conf +UDEVRULES_DIR:=$(sysconfdir)/udev/rules.d + +# Utilities we build with a standard build procedure: +UTILS = dahdi_tool dahdi_test dahdi_monitor dahdi_speed sethdlc dahdi_cfg \ + fxstest fxotune dahdi_diag dahdi_scan + +# some tests: +UTILS += patgen pattest patlooptest hdlcstress hdlctest hdlcgen \ + hdlcverify timertest dahdi_maint + + +BINS:=fxotune dahdi_cfg dahdi_monitor dahdi_speed dahdi_test dahdi_scan dahdi_maint +ifeq (1,$(PBX_NEWT)) + BINS += dahdi_tool +endif +ifeq (1,$(PBX_HDLC)) + BINS += sethdlc +endif +ASSIGNED_DATA_SCRIPTS:=\ + dahdi_handle_device \ + dahdi_span_config \ + dahdi_auto_assign_compat \ + span_config.d/10-dahdi-cfg \ + span_config.d/20-fxotune \ + span_config.d/50-asterisk \ + handle_device.d/10-span-types \ + handle_device.d/20-span-assignments + +ASSIGNED_UTILS:=dahdi_span_assignments dahdi_span_types \ + dahdi_waitfor_span_assignments +ASSIGNED_CONF:=assigned-spans.conf.sample span-types.conf.sample + +MAN_PAGES:= \ + $(wildcard $(BINS:%=doc/%.8)) \ + $(wildcard $(ASSIGNED_UTILS:%=doc/%.8)) + +TEST_BINS:=patgen pattest patlooptest hdlcstress hdlctest hdlcgen hdlcverify timertest dahdi_maint +# All the man pages. Not just installed ones: +GROFF_PAGES := $(wildcard doc/*.8 xpp/*.8) +GROFF_HTML := $(GROFF_PAGES:%=%.html) + +GENERATED_DOCS := $(GROFF_HTML) README.html README.Astribank.html + +all: prereq programs + +libs: $(LTZ_SO) $(LTZ_A) + +utils-subdirs: + @for dir in $(SUBDIRS_UTILS); do \ + $(MAKE) -C $$dir; \ + done + +programs: libs utils + +utils: $(BINS) utils-subdirs + +version.c: FORCE + @TOOLSVERSION="${TOOLSVERSION}" build_tools/make_version_c > $@.tmp + @if cmp -s $@.tmp $@ ; then :; else \ + mv $@.tmp $@ ; \ + fi + @rm -f $@.tmp + +tests: $(TEST_BINS) + +$(UTILS): %: %.o + +$(UTILS): version.o + +%.o: %.c + $(CC) $(CFLAGS) $(MAKE_DEPS) -c -o $@ $< + +%.lo: %.c + $(CC) $(CFLAGS) $(MAKE_DEPS) -c -o $@ $< + +%: %.o + $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ + +prereq: config.status + +dahdi_tool: CFLAGS+=$(NEWT_INCLUDE) +dahdi_tool: LIBS+=$(NEWT_LIB) + +dahdi_speed: CFLAGS+=-O0 + +$(LTZ_A): $(LTZ_A_OBJS) + ar rcs $@ $^ + ranlib $@ + +$(LTZ_SO): $(LTZ_SO_OBJS) + $(CC) $(CFLAGS) -shared -Wl,-soname,$(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) -o $@ $^ -lm + +dahdi_cfg: $(LTZ_A) +dahdi_cfg: LIBS+=-lm -lpthread +dahdi_pcap: + $(CC) $(CFLAGS) dahdi_pcap.c -lpcap -o $@ $< + + +fxstest: $(LTZ_SO) +fxstest: LIBS+=-lm +fxotune: LIBS+=-lm + +tonezones.txt: zonedata.c + perl -ne 'next unless (/\.(country|description) = *"([^"]*)/); \ + print (($$1 eq "country")? "* $$2\t":"$$2\n");' $< \ + >$@ + +%.asciidoc: %.sample + perl -n -e \ + 'if (/^#($$|\s)(.*)/){ if (!$$in_doc){print "\n"}; $$in_doc=1; print "$$2\n" } else { if ($$in_doc){print "\n"}; $$in_doc=0; print " $$_" }' \ + $< \ + | perl -p -e 'if (/^ #?(\w+)=/ && ! exists $$cfgs{$$1}){my $$cfg = $$1; $$cfgs{$$cfg} = 1; s/^/\n[[cfg_$$cfg]]\n/}' >$@ + +docs: $(GENERATED_DOCS) + +genconf_parameters.sample: xpp/genconf_parameters + cp $< $@ + +README.html: README system.conf.asciidoc init.conf.asciidoc tonezones.txt \ + UPGRADE.txt genconf_parameters.asciidoc assigned-spans.conf.asciidoc \ + span-types.conf.asciidoc + $(ASCIIDOC) -n -a toc -a toclevels=4 $< + +README.Astribank.html: xpp/README.Astribank + $(ASCIIDOC) -o $@ -n -a toc -a toclevels=4 $< + +# on Debian: this requires the full groff, not just groff-base. +%.8.html: %.8 + man -Thtml $^ >$@ + +htmlman: $(GROFF_HTML) + +install: all install-programs + @echo "###################################################" + @echo "###" + @echo "### DAHDI tools installed successfully." + @echo "### If you have not done so before, install init scripts with:" + @echo "###" + @echo "### make config" + @echo "###" + @echo "###################################################" + +install-programs: install-utils install-libs + +install-utils: utils install-utils-subdirs +ifneq (,$(BINS)) + install -d $(DESTDIR)$(BIN_DIR) + install $(BINS) $(DESTDIR)$(BIN_DIR)/ + install -d $(DESTDIR)$(MAN_DIR) + install -m 644 $(MAN_PAGES) $(DESTDIR)$(MAN_DIR)/ +endif +ifeq (,$(wildcard $(DESTDIR)$(CONFIG_FILE))) + $(INSTALL) -d $(DESTDIR)$(CONFIG_DIR) + $(INSTALL) -m 644 system.conf.sample $(DESTDIR)$(CONFIG_FILE) +endif + install -d $(DESTDIR)$(DATA_DIR) + tar cf - -C hotplug $(ASSIGNED_DATA_SCRIPTS) | tar xf - -C $(DESTDIR)$(DATA_DIR)/ + install $(ASSIGNED_UTILS) $(DESTDIR)/$(BIN_DIR)/ + install -m 644 $(ASSIGNED_CONF) $(DESTDIR)/$(CONFIG_DIR)/ + install -d $(DESTDIR)$(BASH_COMP_DIR) + install -m 644 dahdi-bash-completion $(DESTDIR)$(BASH_COMP_FILE) + +install-libs: libs + $(INSTALL) -d -m 755 $(DESTDIR)/$(LIB_DIR) + $(INSTALL) -m 755 $(LTZ_A) $(DESTDIR)$(LIB_DIR)/ + $(INSTALL) -m 755 $(LTZ_SO) $(DESTDIR)$(LIB_DIR)/$(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) +ifeq (,$(DESTDIR)) + if [ `id -u` = 0 ]; then \ + /sbin/ldconfig || : ;\ + fi +endif + rm -f $(DESTDIR)$(LIB_DIR)/$(LTZ_SO) + $(LN) -sf $(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) \ + $(DESTDIR)$(LIB_DIR)/$(LTZ_SO).$(LTZ_SO_MAJOR_VER) + $(LN) -sf $(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) \ + $(DESTDIR)$(LIB_DIR)/$(LTZ_SO) + # Overwrite the 1.0 links out there. dahdi-tools 2.0.0 installed + # 1.0 links but dahdi-tools changed them to 2.0 in order to explicitly + # break applications linked with zaptel. But, this also meant that + # applications linked with libtonezone.so.1.0 broke when dahdi-tools + # 2.1.0 was installed. + $(LN) -sf $(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) \ + $(DESTDIR)$(LIB_DIR)/$(LTZ_SO).1.0 + $(LN) -sf $(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) \ + $(DESTDIR)$(LIB_DIR)/$(LTZ_SO).1 +ifneq (no,$(USE_SELINUX)) + ifeq (,$(DESTDIR)) + /sbin/restorecon -v $(DESTDIR)$(LIB_DIR)/$(LTZ_SO) + endif +endif + $(INSTALL) -d -m 755 $(DESTDIR)/$(INC_DIR) + $(INSTALL) -m 644 tonezone.h $(DESTDIR)$(INC_DIR)/ + +install-utils-subdirs: + @for dir in $(SUBDIRS_UTILS); do \ + $(MAKE) -C $$dir install; \ + done + +install-tests: tests +ifneq (,$(TEST_BINS)) + install -d $(DESTDIR)$(BIN_DIR) + install $(TEST_BINS) $(DESTDIR)$(BIN_DIR)/ +endif + +config: +ifneq (,$(COPY_INITD)) + $(COPY_INITD) +endif +ifeq (,$(wildcard $(DESTDIR)$(RCCONF_FILE))) + $(INSTALL) -D -m 644 init.conf.sample $(DESTDIR)$(RCCONF_FILE) +endif +ifeq (,$(wildcard $(DESTDIR)$(MODULES_FILE))) + $(INSTALL) -D -m 644 modules.sample $(DESTDIR)$(MODULES_FILE) +endif +ifeq (,$(wildcard $(DESTDIR)$(GENCONF_FILE))) + $(INSTALL) -D -m 644 xpp/genconf_parameters $(DESTDIR)$(GENCONF_FILE) +endif +ifeq (,$(wildcard $(DESTDIR)$(MODPROBE_FILE))) + $(INSTALL) -D -m 644 modprobe.conf.sample $(DESTDIR)$(MODPROBE_FILE) +endif +ifeq (,$(wildcard $(DESTDIR)$(BLACKLIST_FILE))) + $(INSTALL) -D -m 644 blacklist.sample $(DESTDIR)$(BLACKLIST_FILE) +endif + $(INSTALL) -d $(DESTDIR)$(UDEVRULES_DIR) + $(INSTALL) -D -m 644 dahdi.rules $(DESTDIR)$(UDEVRULES_DIR)/ +ifneq (,$(COPY_NETSCR)) + $(COPY_NETSCR) +endif +ifneq (,$(ADD_INITD)) + $(ADD_INITD) +endif + @echo "DAHDI has been configured." + @echo "" + @echo "List of detected DAHDI devices:" + @echo "" + @if [ `xpp/dahdi_hardware | tee /dev/stderr | wc -l` -eq 0 ]; then \ + echo "No hardware found"; \ + else \ + echo ""; \ + echo "run 'dahdi_genconf modules' to load support for only " ;\ + echo "the DAHDI hardware installed in this system. By "; \ + echo "default support for all DAHDI hardware is loaded at "; \ + echo "DAHDI start. "; \ + fi + +update: + @if [ -d .svn ]; then \ + echo "Updating from Subversion..." ; \ + svn update | tee update.out; \ + rm -f .version; \ + if [ `grep -c ^C update.out` -gt 0 ]; then \ + echo ; echo "The following files have conflicts:" ; \ + grep ^C update.out | cut -b4- ; \ + fi ; \ + rm -f update.out; \ + else \ + echo "Not under version control"; \ + fi + +dist: + @./build_tools/make_dist "dahdi-tools" "$(TOOLSVERSION)" + +clean: + rm -f $(BINS) $(TEST_BINS) + rm -f *.o dahdi_cfg tzdriver sethdlc + rm -f $(LTZ_SO) $(LTZ_A) *.lo + @for dir in $(SUBDIRS_UTILS_ALL); do \ + $(MAKE) -C $$dir clean; \ + done + @for dir in $(SUBDIRS_UTILS); do \ + $(MAKE) -C $$dir clean; \ + done + rm -f libtonezone* + rm -f fxotune + rm -f core + rm -f dahdi_cfg-shared fxstest + rm -rf $(GENERATED_DOCS) *.asciidoc tonezones.txt + rm -f dahdi_pcap + +distclean: dist-clean + +dist-clean: clean + rm -f makeopts + rm -f config.log config.status + rm -f .*.d + +config.status: configure + @CFLAGS="" ./configure + @echo "****" + @echo "**** The configure script was just executed, so 'make' needs to be" + @echo "**** restarted." + @echo "****" + @exit 1 + +.PHONY: distclean dist-clean clean all install programs tests devel data config update install-programs install-libs install-utils-subdirs utils-subdirs prereq dist + +FORCE: + +ifneq ($(wildcard .*.d),) + include .*.d +endif diff --git a/README b/README new file mode 100644 index 0000000..2fadf61 --- /dev/null +++ b/README @@ -0,0 +1,371 @@ +DAHDI Telephony Interface Driver +================================= +Asterisk Development Team +$Revision$, $Date$ + +DAHDI stands for Digium Asterisk Hardware Device Interface. This +package contains the user-space tools to configure the kernel modules +included in the package dahdi-linux. + +Build Requirements +------------------ +This package needs the headers from dahdi-linux. Thus you should install +dahdi-linux before building dahdi-tools. + +Build System +~~~~~~~~~~~~ +GCC and friends. Generally you will need to install the package gcc. +There may be cases where you will need a specific version of gcc to build +kernel modules. + + +Extra Libraries +~~~~~~~~~~~~~~~ +Some libraries are needed for extra utilities that are provided with +DAHDI. + +- libusb is needed for building fpga_load, needed for firmware loading of + the Xorcom Astribank. +- libnewt is needed to build the optional but useful utility dahdi_tool. + + +Installation +~~~~~~~~~~~~ +Note: If using `sudo` to build/install, you may need to add /sbin to your PATH. +---------------------------------- +./configure +make +make install +# To install init scripts and config files: +#make config +---------------------------------- + + +Build Tweaks +~~~~~~~~~~~~ +Partial Build/Install +^^^^^^^^^^^^^^^^^^^^^ +There are some make targets that are provided to build or install just +parts of DAHDI: + +. Build targets: + - make: Build DAHDI user-space programs and libraries. partial + targets of it: + * make 'utilname': builds 'utilname' alone (e.g: `make dahdi_diag`) + * make utils: Build just the programs. + * make libs: Build libtonezone. + * make tests: Build testing binaries. +. Install targets: + - make install: Install everything. Sub-targets of it: + * make install-utils: Installs most things. + * make install-libs: Installs libtonezone. + - make config: install configuration files (overriding existing ones). + - make install-test: Install testing binaries. + + +Installation to a Subtree +^^^^^^^^^^^^^^^^^^^^^^^^^ +The following may be useful when testing the package or when preparing a +package for a binary distribution (such as an rpm package) installing +onto a subtree rather than on the real system. + + make install DESTDIR=targetdir + +This can be useful for any partial install target from the list above. + + +Options For ./configure +^^^^^^^^^^^^^^^^^^^^^^^ +The configure script executes various tests and based on them generates +makeopts. You can pass it --with options and variable settings, for +instance: + + ./configure --without-ncurses CC="gcc-4.10" + +If you just want to recreate the same files without a full detection +run, use: + + ./config.status + +To re-run ./configure with the same parameters it was run with last +time, use: + + ./config.status --recheck + + +Configuration +------------- +Configuration for DAHDI resides under /etc/dahdi . + +/etc/dahdi/system.conf +~~~~~~~~~~~~~~~~~~~~~~ +The main method to configure DAHDI devices is using the utility +*dahdi_cfg*. dahdi_cfg reads data from the configuration file +/etc/dahdi/system.conf , figures out what configuration to send to +channels, and send it to the kernel. + +A sample annotated system.conf is included in this directory and +installed by default. Edit it to suit your configuration. Alternatively +use the script dahdi_genconf to generate one that should work with your +system. Note that while dahdi_genconf will generate a working configuration, +it will not automatically detect hardware echo cancellation modules. These +will have to be enabled manually in system.conf. + +/etc/dahdi/init.conf +~~~~~~~~~~~~~~~~~~~~ +The configuration file of the dahdi init.d script is +/etc/dahdi/init.conf . That file is used to override defaults that are +set at the beginning of the init.d script. + +Reference Configuration +~~~~~~~~~~~~~~~~~~~~~~~ +Sample system.conf +^^^^^^^^^^^^^^^^^^ +include::system.conf.asciidoc[] + + +Sample init.conf +^^^^^^^^^^^^^^^^ +include::init.conf.asciidoc[] + + +Sample genconf_parameters +^^^^^^^^^^^^^^^^^^^^^^^^^ +FIXME: still not properly formatted. + +include::genconf_parameters.asciidoc[] + + +Sample assigned-spans.conf +^^^^^^^^^^^^^^^^^^^^^^^^^^ +include::assigned-spans.conf.asciidoc[] + + +Sample span-types.conf +^^^^^^^^^^^^^^^^^^^^^^ +include::span-types.conf.asciidoc[] + + +Tonezones +~~~~~~~~~ +The file zonedata.c contains the information about the tone zones used +in libtonezone (and hence also in dahdi_cfg). Here is a list of those zones: + +include::tonezones.txt[] + + +DAHDI PERL modules +~~~~~~~~~~~~~~~~~~ +The directory xpp has, in addition to helper utilities for the +Xorcom Astribank, a collection of PERL modules to provide information +related to DAHDI. The PERL modules themselves are under xpp/perl_modules/ . +In xpp/ there are several utilities that use those modules: +- xpp-specific: dahdi_registration, xpp_sync, xpp_blink . +- General: lsdahdi, dahdi_genconf, dahdi_hardware, dahdi_drivers + +The DAHDI PERL modules will currently only be automatically installed if you +happen to install the xpp directory. Those utilities require the PERL modules +to be installed, however they will also look for them in the directory +perl_modules, and thus can be run directly from the DAHDI source tree. For +example: + + ./xpp/dahdi_hardware -v + +To get usage information on a program, you can also use perldoc +(sometimes provided in a package separate from perl itself). For +instance: + + perldoc ./xpp/lsdahdi + +Some of them are specific for the Xorcom Astribank and described in its +documentation. the others are: + +lsdahdi:: + A somewhat glorified `cat /proc/dahdi/*`. +dahdi_genconf:: + Generates configuration based on the existing DAHDI channels and on + /etc/dahdi/genconf_parameters (replaces genzaptelconf as well). +dahdi_drivers:: + A two-liner script (not installed by default) that simply returns the + modules that should be modprobe-d on this system. +dahdi_hardware:: + Uses the information from SysFS and its own knowledge to show + what PCI/USB DAHDI hardware is connected and if it is currently used + by a driver. Shows also some more information for Astribanks from + /proc/xpp . + + +PPP Support +~~~~~~~~~~~ +DAHDI digital cards can provide data channels through PPP as +point-to-point connections. This requires a plug-in to the PPP daemon +that is included in the ppp/ subdirectory. To install it: + +1. Make sure you have the PPP source / headers installed. On Debian: + + apt-get install ppp-dev + +2. Run 'make' on the ppp subdirectory: + + make -C ppp + make -C ppp install + +3. Make sure your kernel has support for both PPP (which is common is + distribution kernels and for HDLC (much less common) - CONFIG_PPP and + CONFIG_HDLC . + + +Initialization +-------------- +This section documents the start up sequence of the DAHDI modules. + +There are generally two options: explicit (using an init script) and +implicit (run from UDEV hook scripts). + +Explicit +~~~~~~~~ +The dahdi init scripts does the following tasks: + +* Loading the module dahdi and any other module listed in + /etc/dahdi/modules. +* For xpp (Astribanks) - some specific initializations. See + README.Astribank. +* Runs link:doc/dahdi_cfg.8.html[dahdi_cfg] after all modules were + loaded. +* A number of other tools may need to be run: +** link:doc/fxotune.8.html[fxotune] +** dahdihpec_enable + +Only at this point Asterisk (or any other user of DAHDI) can be run. + + +Implicit +~~~~~~~~ +(Also known as "hot-plug" or "pinned-spans". This requires: + +* dahdi >= 2.8.0 +* Setting the module parameter auto_assign_spans of dahdi to 0 +* (Recommended) Asterisk >= 12 - which supports "dahdi create channels". + +When a device driver of a DAHDI device finishes initialization, it +creates a dahdi_device kernel object. A dahdi_device represents a single +DAHDI device (such as a PCI card) and may have several spans. If the +value of auto_assign_spans is 1 when dahdi_device is created, spans are +assigned automatically - each new span gets the first available span +number and range of channels. However if it is set to 0, spans will not +get assigned, and user space programs need to assign them. The +low-level interface for doing so is explained in the section "Span +Assignment" in the README of DAHDI-Linux. + +New Devices +^^^^^^^^^^^ +When a kernel object is created or destroyed, the kernel sends an event +to user space. Those events are normally handled by udevd. Configurations +for udevd ("udev rules") may be placed in /etc/udev/rules.d or +/lib/udev/rules.d. This package installs rules that instruct udevd to +run the script `/usr/share/dahdi/dahdi_handle_device` on each new +device, which runs all the scripts in `/usr/share/dahdi/handle_device.d`. +Those scripts will: + +* If `/etc/dahdi/span-types.conf` exists, apply it to the device. It is + used for E1/T1/J1 settings. See + <<_sample_span_types_conf,sample span-types.conf>>. + +* If `/etc/dahdi/assigned-spans.conf` exists, assign the span according + to it (if it is not specified there: don't assign it). + used for E1/T1/J1 settings. See + <<_sample_assigned_spans_conf,sample assigned-spans.conf>>. + +* But if that file does not exist, assign the span to the first + available place. + +This script mainly uses the commands +link:doc/dahdi_span_types.8.html[dahdi_span_types] and +link:doc/dahdi_span_assignments.8.html[dahdi_span_assignments]. + +DAHDI devices are listed under `/sys/bus/dahdi_devices/devices`. + +If you want to disable running this script, add the following line to +`/etc/dahdi/init.conf`: +............................. +DAHDI_UDEV_DISABLE_DEVICES=yes +............................. + + +New Spans +^^^^^^^^^ +Once a span is assigned, a kernel object will appear for it. It will be +listed under its device. As a new kernel object was created, an event is +sent to udev. + +The standard DAHDI udev rules instruct udevd to run the script +`/usr/share/dahdi/dahdi_span_config` which runs all the scripts in +`/usr/share/dahdi/span_config.d`. Those script configures the new +span: + +* If system.conf does not exist, generates a temporary configuration + for the span using link:doc/dahdi_genconf.8.html[dahdi_genconf + system]. + +* Runs link:doc/dahdi_cfg.8.html[dahdi_cfg] on the new span (using `-S` + and -C`). + +* Runs `asterisk -rx 'dahdi create channels'` to add the new channels + and spans to Asterisk (if they were configured in advance). + +If you want to disable running this script, add the following line to +`/etc/dahdi/init.conf`: +............................. +DAHDI_UDEV_DISABLE_SPANS=yes +............................. + + +New Channels +^^^^^^^^^^^^ +DAHDI channels have their own representation in the kernel. The standard +udev rules that dahdi-tools includes for them, however, don't run a +script for each device. Each DAHDI channel creates a block device file +at /dev/dahdi/chan/'span'/'rel-chan', where 'span' and 'rel-chan' are +each three-digit numbers (e.g: 035). 'span' is the span number and +'rel-chan' is the channel number relative to the span. + +The udev rules generate the following extra symlinks under /dev/dahdi: + +* /dev/dahdi/'num' - the channel number. As it was originally (but + continues beyond 250). +* /dev/dahdi/devices/'hardware_id'/'rel-span'/'rel-chan' - if the DAHDI + device has a hardware ID field, provide listing of the device's span + and channels. +* /dev/dahdi/devices/@'hardware_id'/'rel-span'/'rel-chan' - likewise for + the connector field. It has a "@" prefix. + + +include::UPGRADE.txt[] + + +License +------- +This package is distributed under the terms of the GNU General Public License +Version 2, except for some components which are distributed under the terms of +the GNU Lesser General Public License Version 2.1. Both licenses are included +in this directory, and each file is clearly marked as to which license applies. + +If you wish to use the DAHDI drivers in an application for which the license +terms are not appropriate (e.g. a proprietary embedded system), licenses under +more flexible terms can be readily obtained through Digium, Inc. at reasonable +cost. + + +Reporting Bugs +-------------- +Please report bug and patches to the Asterisk bug tracker at +http://bugs.digium.com/[] in the "DAHDI" category. + + +Links +----- +- http://asterisk.org/[] - The Asterisk PBX +- http://voip-info.org/[] +- http://voip-info.org/wiki/view/DAHDI[] +- http://docs.tzafrir.org.il/dahdi-tools/README.html[Up-to-date HTML version + of this file] diff --git a/UPGRADE.txt b/UPGRADE.txt new file mode 100644 index 0000000..cd694de --- /dev/null +++ b/UPGRADE.txt @@ -0,0 +1,102 @@ +Upgrade Notes +------------- + +Information for upgrading from Zaptel 1.2 or 1.4 to DAHDI 2.0 + +Upgrading from Zaptel to DAHDI is fairly straightforward; install this +package using the installation instructions, and then reconfigure and +rebuild Asterisk; Asterisk 1.4 releases later than 1.4.21, and all +releases of Asterisk 1.6, will automatically use DAHDI in preference +to Zaptel, even if Zaptel is still installed on the system. + +Important notes about upgrading: + +The Zaptel package, which included both kernel modules and userspace +tools for configuring and managing the modules, has been split into +two packages: + +* dahdi-linux: kernel modules +* dahdi-tools: userspace tools + +In addition, there is a dahdi-linux-complete package that contains both +dahdi-linux and dahdi-tools for simplified installation. + +NOTE: The dahdi-linux and dahdi-tools packages have *separate* +version numbers; they will not be released 'in sync', and it is +perfectly acceptable to use (for example) dahdi-tools 2.0.6 with +dahdi-linux 2.0.11. The dahdi-linux-complete package version number will +always include *both* of these version numbers so that you will know +what is included in it. + + +DAHDI-Linux +~~~~~~~~~~~ +Module Names +^^^^^^^^^^^^ +The primary kernel modules have changed names; the new names are: + + zaptel.ko -> dahdi.ko + ztd-eth.ko -> dahdi_dynamic_eth.ko + ztd-loc.ko -> dahdi_dynamic_loc.ko + ztdummy.ko -> dahdi_dummy.ko + ztdynamic.ko -> dahdi_dynamic.ko + zttranscode.ko -> dahdi_transcode.ko + +* The kernel modules for card drivers have *not* changed names, + although the wcusb and torisa drivers are no longer included. + +* This package no longer includes the 'menuselect' utility for + choosing which modules to build; all modules that can be built are + built automatically. + + +Echo Canceller Modules +^^^^^^^^^^^^^^^^^^^^^^ +It is no longer possible and needed to select a software echo canceler +at compile time to build into dahdi.ko; all four included echo +cancelers (MG2, KB1, SEC and SEC2) are built as loadable modules. +If the Digium HPEC binary object file has been placed into the +proper directory the HPEC module will be built as well. + +Any or all of these modules can be loaded at the same time, and the echo +canceler to be used on the system's channels can be configured using +the dahdi_cfg tool from the dahdi-tools package. + +IMPORTANT: It is *mandatory* to configure an echo canceler for the system's +channels using dahdi_cfg. There is *no* default echo canceler with DAHDI, not +even hardware echo cancellation modules. See +<<_echo_cancellers,section on echo cancellers>> in sample system.conf. + + +DAHDI-Tools +~~~~~~~~~~~ +Many tool names have changed: + + ztcfg -> dahdi_cfg + ztmonitor -> dahdi_monitor + ztscan -> dahdi_scan + ztspeed -> dahdi_speed + zttest -> dahdi_test + zttool -> dahdi_tool + zapconf -> dahdi_genconf (deprecates genzaptelconf) + +* The system configuration file has moved from /etc/zaptel.conf to + <<_sample_system_conf,/etc/dahdi/system.conf>>. + +* The dahdi_cfg tool can now be used to select an echo canceler on a + channel-by-channel basis in the system configuration file; see + system.conf.sample for examples of how to do this. + +* The configuration for XPP init_card_* scripts is done now + in /etc/dahdi/xpp.conf and uses a simple syntax (example included). + For PRI modules, the 'pri_protocol' setting, determines how + to configure it (E1/T1). + +* In Astribank PRI modules, the LED behaviour represents which ports + are *CLOCK MASTER* (red color) and which are *CLOCK SLAVE* (green color). + Usually (but not always), this corresponds to the NT/TE settings in Asterisk. + +* The /etc/sysconfig/zaptel (or /etc/default/zaptel file, depending + on your distribution) is now split into two separate files: + /etc/dahdi/modules control which modules are loaded and module options are + set via /etc/modprobe.d/dahdi. diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 0000000..587445e --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,1113 @@ +# Various support functions for configure.ac in asterisk +# + +# Helper function to check for gcc attributes. +# AST_GCC_ATTRIBUTE([attribute name]) + +AC_DEFUN([AST_GCC_ATTRIBUTE], +[ +AC_MSG_CHECKING(for compiler 'attribute $1' support) +saved_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Werror" +AC_COMPILE_IFELSE( + AC_LANG_PROGRAM([static void __attribute__(($1)) *test(void *muffin, ...) {}], + []), + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED([HAVE_ATTRIBUTE_$1], 1, [Define to 1 if your GCC C compiler supports the '$1' attribute.]), + AC_MSG_RESULT(no)) +] +CFLAGS="$saved_CFLAGS" +) + +# Helper function to setup variables for a package. +# $1 -> the package name. Used in configure.ac and also as a prefix +# for the variables ($1_DIR, $1_INCLUDE, $1_LIB) in makeopts +# $3 -> option name, used in --with-$3 or --without-$3 when calling configure. +# $2 and $4 are just text describing the package (short and long form) + +# AST_EXT_LIB_SETUP([package], [short description], [configure option name], [long description]) + +AC_DEFUN([AST_EXT_LIB_SETUP], +[ + $1_DESCRIP="$2" + $1_OPTION="$3" + AC_ARG_WITH([$3], AC_HELP_STRING([--with-$3=PATH],[use $2 files in PATH $4]), + [ + case ${withval} in + n|no) + USE_$1=no + ;; + y|ye|yes) + ac_mandatory_list="${ac_mandatory_list} $1" + ;; + *) + $1_DIR="${withval}" + ac_mandatory_list="${ac_mandatory_list} $1" + ;; + esac + ]) + PBX_$1=0 + AC_SUBST([$1_LIB]) + AC_SUBST([$1_INCLUDE]) + AC_SUBST([$1_DIR]) + AC_SUBST([PBX_$1]) +]) + +# Check whether any of the mandatory modules are not present, and +# print error messages in case. The mandatory list is built using +# --with-* arguments when invoking configure. + +AC_DEFUN([AST_CHECK_MANDATORY], +[ + AC_MSG_CHECKING([for mandatory modules: ${ac_mandatory_list}]) + err=0; + for i in ${ac_mandatory_list}; do + eval "a=\${PBX_$i}" + if test "x${a}" = "x1" ; then continue; fi + if test ${err} = "0" ; then AC_MSG_RESULT(fail) ; fi + AC_MSG_RESULT() + eval "a=\${${i}_OPTION}" + AC_MSG_NOTICE([***]) + AC_MSG_NOTICE([*** The $i installation appears to be missing or broken.]) + AC_MSG_NOTICE([*** Either correct the installation, or run configure]) + AC_MSG_NOTICE([*** including --without-${a}.]) + err=1 + done + if test $err = 1 ; then exit 1; fi + AC_MSG_RESULT(ok) +]) + +# The next three functions check for the availability of a given package. +# AST_C_DEFINE_CHECK looks for the presence of a #define in a header file, +# AST_C_COMPILE_CHECK can be used for testing for various items in header files, +# AST_EXT_LIB_CHECK looks for a symbol in a given library, or at least +# for the presence of a header file. +# AST_EXT_TOOL_CHECK looks for a symbol in using $1-config to determine CFLAGS and LIBS +# +# They are only run if PBX_$1 != 1 (where $1 is the package), +# so you can call them multiple times and stop at the first matching one. +# On success, they both set PBX_$1 = 1, set $1_INCLUDE and $1_LIB as applicable, +# and also #define HAVE_$1 1 and #define HAVE_$1_VERSION ${last_argument} +# in autoconfig.h so you can tell which test succeeded. +# They should be called after AST_EXT_LIB_SETUP($1, ...) + +# Check if a given macro is defined in a certain header. + +# AST_C_DEFINE_CHECK([package], [macro name], [header file], [version]) +AC_DEFUN([AST_C_DEFINE_CHECK], +[ + if test "x${PBX_$1}" != "x1"; then + AC_MSG_CHECKING([for $2 in $3]) + saved_cppflags="${CPPFLAGS}" + if test "x${$1_DIR}" != "x"; then + $1_INCLUDE="-I${$1_DIR}/include" + fi + CPPFLAGS="${CPPFLAGS} ${$1_INCLUDE}" + + AC_COMPILE_IFELSE( + [ AC_LANG_PROGRAM( [#include <$3>], + [#if defined($2) + int foo = 0; + #else + int foo = bar; + #endif + 0 + ])], + [ AC_MSG_RESULT(yes) + PBX_$1=1 + AC_DEFINE([HAVE_$1], 1, [Define if your system has the $1 headers.]) + AC_DEFINE([HAVE_$1_VERSION], $4, [Define $1 headers version]) + ], + [ AC_MSG_RESULT(no) ] + ) + CPPFLAGS="${saved_cppflags}" + fi + AC_SUBST(PBX_$1) +]) + + +# Check if a given expression will compile using a certain header. + +# AST_C_COMPILE_CHECK([package], [expression], [header file], [version]) +AC_DEFUN([AST_C_COMPILE_CHECK], +[ + if test "x${PBX_$1}" != "x1" -a "${USE_$1}" != "no"; then + AC_MSG_CHECKING([if "$2" compiles using $3]) + saved_cppflags="${CPPFLAGS}" + if test "x${$1_DIR}" != "x"; then + $1_INCLUDE="-I${$1_DIR}/include" + fi + CPPFLAGS="${CPPFLAGS} ${$1_INCLUDE}" + + AC_COMPILE_IFELSE( + [ AC_LANG_PROGRAM( [#include <$3>], + [ $2; ] + )], + [ AC_MSG_RESULT(yes) + PBX_$1=1 + AC_DEFINE([HAVE_$1], 1, [Define if your system has the $1 headers.]) + AC_DEFINE([HAVE_$1_VERSION], $4, [Define $1 headers version]) + ], + [ AC_MSG_RESULT(no) ] + ) + CPPFLAGS="${saved_cppflags}" + fi +]) + + +# Check for existence of a given package ($1), either looking up a function +# in a library, or, if no function is supplied, only check for the +# existence of the header files. + +# AST_EXT_LIB_CHECK([package], [library], [function], [header], +# [extra libs], [extra cflags], [version]) +AC_DEFUN([AST_EXT_LIB_CHECK], +[ +if test "x${PBX_$1}" != "x1" -a "${USE_$1}" != "no"; then + pbxlibdir="" + # if --with-$1=DIR has been specified, use it. + if test "x${$1_DIR}" != "x"; then + if test -d ${$1_DIR}/lib; then + pbxlibdir="-L${$1_DIR}/lib" + else + pbxlibdir="-L${$1_DIR}" + fi + fi + pbxfuncname="$3" + if test "x${pbxfuncname}" = "x" ; then # empty lib, assume only headers + AST_$1_FOUND=yes + else + AC_CHECK_LIB([$2], [${pbxfuncname}], [AST_$1_FOUND=yes], [AST_$1_FOUND=no], ${pbxlibdir} $5) + fi + + # now check for the header. + if test "${AST_$1_FOUND}" = "yes"; then + $1_LIB="${pbxlibdir} -l$2 $5" + # if --with-$1=DIR has been specified, use it. + if test "x${$1_DIR}" != "x"; then + $1_INCLUDE="-I${$1_DIR}/include" + fi + $1_INCLUDE="${$1_INCLUDE} $6" + if test "x$4" = "x" ; then # no header, assume found + $1_HEADER_FOUND="1" + else # check for the header + saved_cppflags="${CPPFLAGS}" + CPPFLAGS="${CPPFLAGS} ${$1_INCLUDE} $6" + AC_CHECK_HEADER([$4], [$1_HEADER_FOUND=1], [$1_HEADER_FOUND=0]) + CPPFLAGS="${saved_cppflags}" + fi + if test "x${$1_HEADER_FOUND}" = "x0" ; then + $1_LIB="" + $1_INCLUDE="" + else + if test "x${pbxfuncname}" = "x" ; then # only checking headers -> no library + $1_LIB="" + fi + PBX_$1=1 + # XXX don't know how to evaluate the description (third argument) in AC_DEFINE_UNQUOTED + AC_DEFINE_UNQUOTED([HAVE_$1], 1, [Define this to indicate the ${$1_DESCRIP} library]) + AC_DEFINE_UNQUOTED([HAVE_$1_VERSION], [$7], [Define to indicate the ${$1_DESCRIP} library version]) + fi + fi +fi +]) + + +# Check for a package using $2-config. Similar to AST_EXT_LIB_CHECK, +# but use $2-config to determine cflags and libraries to use. +# $3 and $4 can be used to replace --cflags and --libs in the request + +# AST_EXT_TOOL_CHECK([package], [tool name], [--cflags], [--libs], [includes], [expression]) +AC_DEFUN([AST_EXT_TOOL_CHECK], +[ + if test "x${PBX_$1}" != "x1" -a "${USE_$1}" != "no"; then + PBX_$1=0 + AC_CHECK_TOOL(CONFIG_$1, $2-config, No) + if test ! "x${CONFIG_$1}" = xNo; then + if test x"$3" = x ; then A=--cflags ; else A="$3" ; fi + $1_INCLUDE=$(${CONFIG_$1} $A) + if test x"$4" = x ; then A=--libs ; else A="$4" ; fi + $1_LIB=$(${CONFIG_$1} $A) + if test x"$5" != x ; then + saved_cppflags="${CPPFLAGS}" + if test "x${$1_DIR}" != "x"; then + $1_INCLUDE="-I${$1_DIR}/include" + fi + CPPFLAGS="${CPPFLAGS} ${$1_INCLUDE}" + + saved_ldflags="${LDFLAGS}" + LDFLAGS="${$1_LIB}" + + AC_LINK_IFELSE( + [ AC_LANG_PROGRAM( [ $5 ], + [ $6; ] + )], + [ PBX_$1=1 + AC_DEFINE([HAVE_$1], 1, [Define if your system has the $1 headers.]) + ], + [] + ) + CPPFLAGS="${saved_cppflags}" + LDFLAGS="${saved_ldflags}" + else + PBX_$1=1 + AC_DEFINE([HAVE_$1], 1, [Define if your system has the $1 libraries.]) + fi + fi + fi +]) + +AC_DEFUN([AST_CHECK_GNU_MAKE], [AC_CACHE_CHECK([for GNU make], [ac_cv_GNU_MAKE], + ac_cv_GNU_MAKE='Not Found' ; + ac_cv_GNU_MAKE_VERSION_MAJOR=0 ; + ac_cv_GNU_MAKE_VERSION_MINOR=0 ; + for a in make gmake gnumake ; do + if test -z "$a" ; then continue ; fi ; + if ( sh -c "$a --version" 2> /dev/null | grep GNU 2>&1 > /dev/null ) ; then + ac_cv_GNU_MAKE=$a ; + ac_cv_GNU_MAKE_VERSION_MAJOR=`$ac_cv_GNU_MAKE --version | grep "GNU Make" | cut -f3 -d' ' | cut -f1 -d'.'` + ac_cv_GNU_MAKE_VERSION_MINOR=`$ac_cv_GNU_MAKE --version | grep "GNU Make" | cut -f2 -d'.' | cut -c1-2` + break; + fi + done ; +) ; +if test "x$ac_cv_GNU_MAKE" = "xNot Found" ; then + AC_MSG_ERROR( *** Please install GNU make. It is required to build Asterisk!) + exit 1 +fi +AC_SUBST([GNU_MAKE], [$ac_cv_GNU_MAKE]) +]) + +AC_DEFUN( +[AST_CHECK_PWLIB], [ +PWLIB_INCDIR= +PWLIB_LIBDIR= +AC_LANG_PUSH([C++]) +if test "${PWLIBDIR:-unset}" != "unset" ; then + AC_CHECK_HEADER(${PWLIBDIR}/version.h, HAS_PWLIB=1, ) +fi +if test "${HAS_PWLIB:-unset}" = "unset" ; then + if test "${OPENH323DIR:-unset}" != "unset"; then + AC_CHECK_HEADER(${OPENH323DIR}/../pwlib/version.h, HAS_PWLIB=1, ) + fi + if test "${HAS_PWLIB:-unset}" != "unset" ; then + PWLIBDIR="${OPENH323DIR}/../pwlib" + else + AC_CHECK_HEADER(${HOME}/pwlib/include/ptlib.h, HAS_PWLIB=1, ) + if test "${HAS_PWLIB:-unset}" != "unset" ; then + PWLIBDIR="${HOME}/pwlib" + else + AC_CHECK_HEADER(/usr/local/include/ptlib.h, HAS_PWLIB=1, ) + if test "${HAS_PWLIB:-unset}" != "unset" ; then + AC_PATH_PROG(PTLIB_CONFIG, ptlib-config, , /usr/local/bin) + if test "${PTLIB_CONFIG:-unset}" = "unset" ; then + AC_PATH_PROG(PTLIB_CONFIG, ptlib-config, , /usr/local/share/pwlib/make) + fi + PWLIB_INCDIR="/usr/local/include" + PWLIB_LIBDIR=`${PTLIB_CONFIG} --pwlibdir` + if test "${PWLIB_LIBDIR:-unset}" = "unset"; then + if test "x$LIB64" != "x"; then + PWLIB_LIBDIR="/usr/local/lib64" + else + PWLIB_LIBDIR="/usr/local/lib" + fi + fi + PWLIB_LIB=`${PTLIB_CONFIG} --ldflags --libs` + PWLIB_LIB="-L${PWLIB_LIBDIR} `echo ${PWLIB_LIB}`" + else + AC_CHECK_HEADER(/usr/include/ptlib.h, HAS_PWLIB=1, ) + if test "${HAS_PWLIB:-unset}" != "unset" ; then + AC_PATH_PROG(PTLIB_CONFIG, ptlib-config, , /usr/share/pwlib/make) + PWLIB_INCDIR="/usr/include" + PWLIB_LIBDIR=`${PTLIB_CONFIG} --pwlibdir` + if test "${PWLIB_LIBDIR:-unset}" = "unset"; then + if test "x$LIB64" != "x"; then + PWLIB_LIBDIR="/usr/lib64" + else + PWLIB_LIBDIR="/usr/lib" + fi + fi + PWLIB_LIB=`${PTLIB_CONFIG} --ldflags --libs` + PWLIB_LIB="-L${PWLIB_LIBDIR} `echo ${PWLIB_LIB}`" + fi + fi + fi + fi +fi + +#if test "${HAS_PWLIB:-unset}" = "unset" ; then +# echo "Cannot find pwlib - please install or set PWLIBDIR and try again" +# exit +#fi + +if test "${HAS_PWLIB:-unset}" != "unset" ; then + if test "${PWLIBDIR:-unset}" = "unset" ; then + if test "${PTLIB_CONFIG:-unset}" != "unset" ; then + PWLIBDIR=`$PTLIB_CONFIG --prefix` + else + echo "Cannot find ptlib-config - please install and try again" + exit + fi + fi + + if test "x$PWLIBDIR" = "x/usr" -o "x$PWLIBDIR" = "x/usr/"; then + PWLIBDIR="/usr/share/pwlib" + PWLIB_INCDIR="/usr/include" + if test "x$LIB64" != "x"; then + PWLIB_LIBDIR="/usr/lib64" + else + PWLIB_LIBDIR="/usr/lib" + fi + fi + if test "x$PWLIBDIR" = "x/usr/local" -o "x$PWLIBDIR" = "x/usr/"; then + PWLIBDIR="/usr/local/share/pwlib" + PWLIB_INCDIR="/usr/local/include" + if test "x$LIB64" != "x"; then + PWLIB_LIBDIR="/usr/local/lib64" + else + PWLIB_LIBDIR="/usr/local/lib" + fi + fi + + if test "${PWLIB_INCDIR:-unset}" = "unset"; then + PWLIB_INCDIR="${PWLIBDIR}/include" + fi + if test "${PWLIB_LIBDIR:-unset}" = "unset"; then + PWLIB_LIBDIR="${PWLIBDIR}/lib" + fi + + AC_SUBST([PWLIBDIR]) + AC_SUBST([PWLIB_INCDIR]) + AC_SUBST([PWLIB_LIBDIR]) +fi + AC_LANG_POP([C++]) +]) + + +AC_DEFUN( +[AST_CHECK_OPENH323_PLATFORM], [ +PWLIB_OSTYPE= +case "$host_os" in + linux*) PWLIB_OSTYPE=linux ; + ;; + freebsd* ) PWLIB_OSTYPE=FreeBSD ; + ;; + openbsd* ) PWLIB_OSTYPE=OpenBSD ; + ENDLDLIBS="-lossaudio" ; + ;; + netbsd* ) PWLIB_OSTYPE=NetBSD ; + ENDLDLIBS="-lossaudio" ; + ;; + solaris* | sunos* ) PWLIB_OSTYPE=solaris ; + ;; + darwin* ) PWLIB_OSTYPE=Darwin ; + ;; + beos*) PWLIB_OSTYPE=beos ; + STDCCFLAGS="$STDCCFLAGS -D__BEOS__" + ;; + cygwin*) PWLIB_OSTYPE=cygwin ; + ;; + mingw*) PWLIB_OSTYPE=mingw ; + STDCCFLAGS="$STDCCFLAGS -mms-bitfields" ; + ENDLDLIBS="-lwinmm -lwsock32 -lsnmpapi -lmpr -lcomdlg32 -lgdi32 -lavicap32" ; + ;; + * ) PWLIB_OSTYPE="$host_os" ; + AC_MSG_WARN("OS $PWLIB_OSTYPE not recognized - proceed with caution!") ; + ;; +esac + +PWLIB_MACHTYPE= +case "$host_cpu" in + x86 | i686 | i586 | i486 | i386 ) PWLIB_MACHTYPE=x86 + ;; + + x86_64) PWLIB_MACHTYPE=x86_64 ; + P_64BIT=1 ; + LIB64=1 ; + ;; + + alpha | alphaev56 | alphaev6 | alphaev67 | alphaev7) PWLIB_MACHTYPE=alpha ; + P_64BIT=1 ; + ;; + + sparc ) PWLIB_MACHTYPE=sparc ; + ;; + + powerpc ) PWLIB_MACHTYPE=ppc ; + ;; + + ppc ) PWLIB_MACHTYPE=ppc ; + ;; + + powerpc64 ) PWLIB_MACHTYPE=ppc64 ; + P_64BIT=1 ; + LIB64=1 ; + ;; + + ppc64 ) PWLIB_MACHTYPE=ppc64 ; + P_64BIT=1 ; + LIB64=1 ; + ;; + + ia64) PWLIB_MACHTYPE=ia64 ; + P_64BIT=1 ; + ;; + + s390x) PWLIB_MACHTYPE=s390x ; + P_64BIT=1 ; + LIB64=1 ; + ;; + + s390) PWLIB_MACHTYPE=s390 ; + ;; + + * ) PWLIB_MACHTYPE="$host_cpu"; + AC_MSG_WARN("CPU $PWLIB_MACHTYPE not recognized - proceed with caution!") ;; +esac + +PWLIB_PLATFORM="${PWLIB_OSTYPE}_${PWLIB_MACHTYPE}" + +AC_SUBST([PWLIB_PLATFORM]) +]) + + +AC_DEFUN( +[AST_CHECK_OPENH323], [ +OPENH323_INCDIR= +OPENH323_LIBDIR= +AC_LANG_PUSH([C++]) +if test "${OPENH323DIR:-unset}" != "unset" ; then + AC_CHECK_HEADER(${OPENH323DIR}/version.h, HAS_OPENH323=1, ) +fi +if test "${HAS_OPENH323:-unset}" = "unset" ; then + AC_CHECK_HEADER(${PWLIBDIR}/../openh323/version.h, OPENH323DIR="${PWLIBDIR}/../openh323"; HAS_OPENH323=1, ) + if test "${HAS_OPENH323:-unset}" != "unset" ; then + OPENH323DIR="${PWLIBDIR}/../openh323" + saved_cppflags="${CPPFLAGS}" + CPPFLAGS="${CPPFLAGS} -I${PWLIB_INCDIR}/openh323 -I${PWLIB_INCDIR}" + AC_CHECK_HEADER(${OPENH323DIR}/include/h323.h, , OPENH323_INCDIR="${PWLIB_INCDIR}/openh323"; OPENH323_LIBDIR="${PWLIB_LIBDIR}", [#include ]) + CPPFLAGS="${saved_cppflags}" + else + saved_cppflags="${CPPFLAGS}" + CPPFLAGS="${CPPFLAGS} -I${HOME}/openh323/include -I${PWLIB_INCDIR}" + AC_CHECK_HEADER(${HOME}/openh323/include/h323.h, HAS_OPENH323=1, ) + CPPFLAGS="${saved_cppflags}" + if test "${HAS_OPENH323:-unset}" != "unset" ; then + OPENH323DIR="${HOME}/openh323" + else + saved_cppflags="${CPPFLAGS}" + CPPFLAGS="${CPPFLAGS} -I/usr/local/include/openh323 -I${PWLIB_INCDIR}" + AC_CHECK_HEADER(/usr/local/include/openh323/h323.h, HAS_OPENH323=1, ) + CPPFLAGS="${saved_cppflags}" + if test "${HAS_OPENH323:-unset}" != "unset" ; then + OPENH323DIR="/usr/local/share/openh323" + OPENH323_INCDIR="/usr/local/include/openh323" + if test "x$LIB64" != "x"; then + OPENH323_LIBDIR="/usr/local/lib64" + else + OPENH323_LIBDIR="/usr/local/lib" + fi + else + saved_cppflags="${CPPFLAGS}" + CPPFLAGS="${CPPFLAGS} -I/usr/include/openh323 -I${PWLIB_INCDIR}" + AC_CHECK_HEADER(/usr/include/openh323/h323.h, HAS_OPENH323=1, , [#include ]) + CPPFLAGS="${saved_cppflags}" + if test "${HAS_OPENH323:-unset}" != "unset" ; then + OPENH323DIR="/usr/share/openh323" + OPENH323_INCDIR="/usr/include/openh323" + if test "x$LIB64" != "x"; then + OPENH323_LIBDIR="/usr/lib64" + else + OPENH323_LIBDIR="/usr/lib" + fi + fi + fi + fi + fi +fi + +if test "${HAS_OPENH323:-unset}" != "unset" ; then + if test "${OPENH323_INCDIR:-unset}" = "unset"; then + OPENH323_INCDIR="${OPENH323DIR}/include" + fi + if test "${OPENH323_LIBDIR:-unset}" = "unset"; then + OPENH323_LIBDIR="${OPENH323DIR}/lib" + fi + + OPENH323_LIBDIR="`cd ${OPENH323_LIBDIR}; pwd`" + OPENH323_INCDIR="`cd ${OPENH323_INCDIR}; pwd`" + OPENH323DIR="`cd ${OPENH323DIR}; pwd`" + + AC_SUBST([OPENH323DIR]) + AC_SUBST([OPENH323_INCDIR]) + AC_SUBST([OPENH323_LIBDIR]) +fi + AC_LANG_POP([C++]) +]) + + +AC_DEFUN( +[AST_CHECK_PWLIB_VERSION], [ + if test "${HAS_$2:-unset}" != "unset"; then + $2_VERSION=`grep "$2_VERSION" ${$2_INCDIR}/$3 | cut -f2 -d ' ' | sed -e 's/"//g'` + $2_MAJOR_VERSION=`echo ${$2_VERSION} | cut -f1 -d.` + $2_MINOR_VERSION=`echo ${$2_VERSION} | cut -f2 -d.` + $2_BUILD_NUMBER=`echo ${$2_VERSION} | cut -f3 -d.` + let $2_VER=${$2_MAJOR_VERSION}*10000+${$2_MINOR_VERSION}*100+${$2_BUILD_NUMBER} + let $2_REQ=$4*10000+$5*100+$6 + + AC_MSG_CHECKING(if $1 version ${$2_VERSION} is compatible with chan_h323) + if test ${$2_VER} -lt ${$2_REQ}; then + AC_MSG_RESULT(no) + unset HAS_$2 + else + AC_MSG_RESULT(yes) + fi + fi +]) + + +AC_DEFUN( +[AST_CHECK_PWLIB_BUILD], [ + if test "${HAS_$2:-unset}" != "unset"; then + AC_MSG_CHECKING($1 installation validity) + + saved_cppflags="${CPPFLAGS}" + saved_libs="${LIBS}" + if test "${$2_LIB:-unset}" != "unset"; then + LIBS="${LIBS} ${$2_LIB} $7" + else + LIBS="${LIBS} -L${$2_LIBDIR} -l${PLATFORM_$2} $7" + fi + CPPFLAGS="${CPPFLAGS} -I${$2_INCDIR} $6" + + AC_LANG_PUSH([C++]) + + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([$4],[$5])], + [ AC_MSG_RESULT(yes) + ac_cv_lib_$2="yes" + ], + [ AC_MSG_RESULT(no) + ac_cv_lib_$2="no" + ] + ) + + AC_LANG_POP([C++]) + + LIBS="${saved_libs}" + CPPFLAGS="${saved_cppflags}" + + if test "${ac_cv_lib_$2}" = "yes"; then + if test "${$2_LIB:-undef}" = "undef"; then + if test "${$2_LIBDIR}" != "" -a "${$2_LIBDIR}" != "/usr/lib"; then + $2_LIB="-L${$2_LIBDIR} -l${PLATFORM_$2}" + else + $2_LIB="-l${PLATFORM_$2}" + fi + fi + if test "${$2_INCDIR}" != "" -a "${$2_INCDIR}" != "/usr/include"; then + $2_INCLUDE="-I${$2_INCDIR}" + fi + PBX_$2=1 + AC_DEFINE([HAVE_$2], 1, [$3]) + fi + fi +]) + +AC_DEFUN( +[AST_CHECK_OPENH323_BUILD], [ + if test "${HAS_OPENH323:-unset}" != "unset"; then + AC_MSG_CHECKING(OpenH323 build option) + OPENH323_SUFFIX= + prefixes="h323_${PWLIB_PLATFORM}_ h323_ openh323" + for pfx in $prefixes; do + files=`ls -l ${OPENH323_LIBDIR}/lib${pfx}*.so* 2>/dev/null` + libfile= + if test -n "$files"; then + for f in $files; do + if test -f $f -a ! -L $f; then + libfile=`basename $f` + break; + fi + done + fi + if test -n "$libfile"; then + OPENH323_PREFIX=$pfx + break; + fi + done + if test "${libfile:-unset}" != "unset"; then + OPENH323_SUFFIX=`eval "echo ${libfile} | sed -e 's/lib${OPENH323_PREFIX}\(@<:@^.@:>@*\)\..*/\1/'"` + fi + case "${OPENH323_SUFFIX}" in + n) + OPENH323_BUILD="notrace";; + r) + OPENH323_BUILD="opt";; + d) + OPENH323_BUILD="debug";; + *) + if test "${OPENH323_PREFIX:-undef}" = "openh323"; then + notrace=`eval "grep NOTRACE ${OPENH323DIR}/openh323u.mak | grep = | sed -e 's/@<:@A-Z0-9_@:>@*@<:@ @:>@*=@<:@ @:>@*//'"` + if test "x$notrace" = "x"; then + notrace="0" + fi + if test "$notrace" -ne 0; then + OPENH323_BUILD="notrace" + else + OPENH323_BUILD="opt" + fi + OPENH323_LIB="-l${OPENH323_PREFIX}" + else + OPENH323_BUILD="notrace" + fi + ;; + esac + AC_MSG_RESULT(${OPENH323_BUILD}) + + AC_SUBST([OPENH323_SUFFIX]) + AC_SUBST([OPENH323_BUILD]) + fi +]) + + +# AST_FUNC_FORK +# ------------- +AN_FUNCTION([fork], [AST_FUNC_FORK]) +AN_FUNCTION([vfork], [AST_FUNC_FORK]) +AC_DEFUN([AST_FUNC_FORK], +[AC_REQUIRE([AC_TYPE_PID_T])dnl +AC_CHECK_HEADERS(vfork.h) +AC_CHECK_FUNCS(fork vfork) +if test "x$ac_cv_func_fork" = xyes; then + _AST_FUNC_FORK +else + ac_cv_func_fork_works=$ac_cv_func_fork +fi +if test "x$ac_cv_func_fork_works" = xcross; then + case $host in + *-*-amigaos* | *-*-msdosdjgpp* | *-*-uclinux* | *-*-linux-uclibc* ) + # Override, as these systems have only a dummy fork() stub + ac_cv_func_fork_works=no + ;; + *) + ac_cv_func_fork_works=yes + ;; + esac + AC_MSG_WARN([result $ac_cv_func_fork_works guessed because of cross compilation]) +fi +ac_cv_func_vfork_works=$ac_cv_func_vfork +if test "x$ac_cv_func_vfork" = xyes; then + _AC_FUNC_VFORK +fi; +if test "x$ac_cv_func_fork_works" = xcross; then + ac_cv_func_vfork_works=$ac_cv_func_vfork + AC_MSG_WARN([result $ac_cv_func_vfork_works guessed because of cross compilation]) +fi + +if test "x$ac_cv_func_vfork_works" = xyes; then + AC_DEFINE(HAVE_WORKING_VFORK, 1, [Define to 1 if `vfork' works.]) +else + AC_DEFINE(vfork, fork, [Define as `fork' if `vfork' does not work.]) +fi +if test "x$ac_cv_func_fork_works" = xyes; then + AC_DEFINE(HAVE_WORKING_FORK, 1, [Define to 1 if `fork' works.]) +fi +])# AST_FUNC_FORK + + +# _AST_FUNC_FORK +# ------------- +AC_DEFUN([_AST_FUNC_FORK], + [AC_CACHE_CHECK(for working fork, ac_cv_func_fork_works, + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT], + [ + /* By Ruediger Kuhlmann. */ + return fork () < 0; + ])], + [ac_cv_func_fork_works=yes], + [ac_cv_func_fork_works=no], + [ac_cv_func_fork_works=cross])])] +)# _AST_FUNC_FORK + +# AST_PROG_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([AST_PROG_LD], +[AC_ARG_WITH([gnu-ld], + [AC_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no]) +AC_REQUIRE([AST_PROG_SED])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi]) + EGREP=$ac_cv_prog_egrep + AC_SUBST([EGREP]) +])]) # AST_PROG_EGREP + +# AST_PROG_SED +# ----------- +# Check for a fully functional sed program that truncates +# as few characters as possible. Prefer GNU sed if found. +AC_DEFUN([AST_PROG_SED], +[AC_CACHE_CHECK([for a sed that does not truncate output], ac_cv_path_SED, + [dnl ac_script should not contain more than 99 commands (for HP-UX sed), + dnl but more than about 7000 bytes, to catch a limit in Solaris 8 /usr/ucb/sed. + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" | sed 99q >conftest.sed + $as_unset ac_script || ac_script= + _AC_PATH_PROG_FEATURE_CHECK(SED, [sed gsed], + [_AC_FEATURE_CHECK_LENGTH([ac_path_SED], [ac_cv_path_SED], + ["$ac_path_SED" -f conftest.sed])])]) + SED="$ac_cv_path_SED" + AC_SUBST([SED])dnl + rm -f conftest.sed +])# AST_PROG_SED + +dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +dnl +dnl @summary figure out how to build C programs using POSIX threads +dnl +dnl This macro figures out how to build C programs using POSIX threads. +dnl It sets the PTHREAD_LIBS output variable to the threads library and +dnl linker flags, and the PTHREAD_CFLAGS output variable to any special +dnl C compiler flags that are needed. (The user can also force certain +dnl compiler flags/libs to be tested by setting these environment +dnl variables.) +dnl +dnl Also sets PTHREAD_CC to any special C compiler that is needed for +dnl multi-threaded programs (defaults to the value of CC otherwise). +dnl (This is necessary on AIX to use the special cc_r compiler alias.) +dnl +dnl NOTE: You are assumed to not only compile your program with these +dnl flags, but also link it with them as well. e.g. you should link +dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS +dnl $LIBS +dnl +dnl If you are only building threads programs, you may wish to use +dnl these variables in your default LIBS, CFLAGS, and CC: +dnl +dnl LIBS="$PTHREAD_LIBS $LIBS" +dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +dnl CC="$PTHREAD_CC" +dnl +dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute +dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to +dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +dnl +dnl ACTION-IF-FOUND is a list of shell commands to run if a threads +dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to +dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the +dnl default action will define HAVE_PTHREAD. +dnl +dnl Please let the authors know if this macro fails on any platform, or +dnl if you have any other suggestions or comments. This macro was based +dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with +dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros +dnl posted by Alejandro Forero Cuervo to the autoconf macro repository. +dnl We are also grateful for the helpful feedback of numerous users. +dnl +dnl @category InstalledPackages +dnl @author Steven G. Johnson +dnl @version 2006-05-29 +dnl @license GPLWithACException + +AC_DEFUN([ACX_PTHREAD], +[ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_SAVE +AC_LANG_C +acx_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) + AC_MSG_RESULT($acx_pthread_ok) + if test x"$acx_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case "${host_cpu}-${host_os}" in + *solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" + ;; +esac + +if test x"$acx_pthread_ok" = xno; then +for flag in $acx_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) + if test x"$acx_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [acx_pthread_ok=yes]) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT($acx_pthread_ok) + if test "x$acx_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$acx_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_MSG_CHECKING([for joinable pthread attribute]) + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_TRY_LINK([#include ], [int attr=$attr; return attr;], + [attr_name=$attr; break]) + done + AC_MSG_RESULT($attr_name) + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case "${host_cpu}-${host_os}" in + *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: must compile with xlc_r or cc_r + if test x"$GCC" != xyes; then + AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) + else + PTHREAD_CC=$CC + fi +else + PTHREAD_CC="$CC" +fi + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_CC) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$acx_pthread_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + : +else + acx_pthread_ok=no + $2 +fi +AC_LANG_RESTORE +])dnl ACX_PTHREAD diff --git a/assigned-spans.conf.sample b/assigned-spans.conf.sample new file mode 100644 index 0000000..6f83aac --- /dev/null +++ b/assigned-spans.conf.sample @@ -0,0 +1,57 @@ +# +# /etc/dahdi/assigned-spans.conf: +# +# This file assigns span and channel numbers to dahdi devices +# +# Built as a table keyed by : +# .... +# +# Where: +# * The field may be either: +# hardware_id +# @location +# devpath (in sysfs) +# * Shell-style globbing is allowed for the field +# * There may one or more of +# * Each is composed as: +# :: +# +# Examples: + +# Astribank with two spans: +# FXS * 8 channels + 4 digital inputs 2 digital outputs +# FXO * 8 channels +#usb:QA-1 1:1:1 +#usb:QA-1 2:2:15 + +# Same Astribank in one-liner +#usb:QA-1 1:1:1 2:2:15 + +# Astribank with 4*PRI spans and 3*FXS*8 spans +# Note that channels are NOT globally contigous +# each span get its own 50 numbers. Also, skip +# Channel number 250... +#usb:INT03165 1:1:1 # E1 +#usb:INT03165 2:2:51 # E1 +#usb:INT03165 3:3:151 # E1 +#usb:INT03165 4:4:201 # E1 +#usb:INT03165 5:5:301 # FXS * 8 channels +#usb:INT03165 6:6:351 # FXS * 8 channels +#usb:INT03165 7:7:401 # FXS * 8 channels + +# Alternatively -- all in one-line +#usb:INT03165 1:1:1 2:2:51 3:3:151 4:4:201 5:5:301 6:6:351 7:7:401 + +# Astribank with 4*BRI without hardware_id :-( +# We use the location on the bus (ie: where it is physically +# located). Note the '@' prefix that indicate the location key. +#@usb-0000:00:1d.7-3 1:1:50 +#@usb-0000:00:1d.7-3 2:2:100 +#@usb-0000:00:1d.7-3 3:3:150 +#@usb-0000:00:1d.7-3 4:4:200 + +# Same configuration with globbing: +#/sys/*/usb1/1-6/* 1:1:50 +#/sys/*/usb1/1-6/* 2:2:100 +#/sys/*/usb1/1-6/* 3:3:150 +#/sys/*/usb1/1-6/* 4:4:200 diff --git a/autoconfig.h.in b/autoconfig.h.in new file mode 100644 index 0000000..67aef05 --- /dev/null +++ b/autoconfig.h.in @@ -0,0 +1,114 @@ +/* autoconfig.h.in. Generated from configure.ac by autoheader. */ + +/* Define if your system has the DAHDI headers. */ +#undef HAVE_DAHDI + +/* Define if your system has the DAHDI23 headers. */ +#undef HAVE_DAHDI23 + +/* Define DAHDI23 headers version */ +#undef HAVE_DAHDI23_VERSION + +/* Define DAHDI headers version */ +#undef HAVE_DAHDI_VERSION + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_SOUNDCARD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define this to indicate the ${NEWT_DESCRIP} library */ +#undef HAVE_NEWT + +/* Define to indicate the ${NEWT_DESCRIP} library version */ +#undef HAVE_NEWT_VERSION + +/* Define to 1 if you have the `semtimedop' function. */ +#undef HAVE_SEMTIMEDOP + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOUNDCARD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define this to indicate the ${USB_DESCRIP} library */ +#undef HAVE_USB + +/* Define to indicate the ${USB_DESCRIP} library version */ +#undef HAVE_USB_VERSION + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif + + +/* Define to 1 if on MINIX. */ +#undef _MINIX + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +#undef _POSIX_1_SOURCE + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +#undef _POSIX_SOURCE diff --git a/bittest.h b/bittest.h new file mode 100644 index 0000000..c9b9eb2 --- /dev/null +++ b/bittest.h @@ -0,0 +1,17 @@ +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +static int bit_next(int prev) +{ + return (prev + 1) % 256; +} diff --git a/blacklist.sample b/blacklist.sample new file mode 100644 index 0000000..f054e28 --- /dev/null +++ b/blacklist.sample @@ -0,0 +1,23 @@ +# blacklist all the drivers by default in order to ensure that +# /etc/init.d/dahdi installs them in the correct order so that the spans are +# ordered consistently. + +blacklist wct4xxp +blacklist wcte12xp +blacklist wcte13xp +blacklist wct1xxp +blacklist wcte11xp +blacklist wctdm24xxp +blacklist wcfxo +blacklist wctdm +blacklist wctc4xxp +blacklist wcb4xxp +blacklist wcaxx +blacklist wcte43x + +# Some mISDN drivers may try to attach to cards supported by DAHDI. If you +# have a card which is *not* supported by DAHDI but supported by one of the +# below drivers you should feel free to remove it from the blacklist below. +blacklist hfcmulti +blacklist netjet +blacklist hfcpci diff --git a/bootstrap.sh b/bootstrap.sh new file mode 100755 index 0000000..570d66c --- /dev/null +++ b/bootstrap.sh @@ -0,0 +1,48 @@ +#!/bin/sh + +check_for_app() { + $1 --version 2>&1 >/dev/null + if [ $? != 0 ] + then + echo "Please install $1 and run bootstrap.sh again!" + exit 1 + fi +} + +# On FreeBSD and OpenBSD, multiple autoconf/automake versions have different names. +# On linux, envitonment variables tell which one to use. + +uname -s | grep -q BSD +if [ $? = 0 ] ; then # BSD case + case `uname -sr` in + 'FreeBSD 4'*) # FreeBSD 4.x has a different naming + MY_AC_VER=259 + MY_AM_VER=19 + ;; + *) + MY_AC_VER=-2.62 + MY_AM_VER=-1.9 + ;; + esac +else # linux case + MY_AC_VER= + MY_AM_VER= + AUTOCONF_VERSION=2.60 + AUTOMAKE_VERSION=1.9 + export AUTOCONF_VERSION + export AUTOMAKE_VERSION +fi + +check_for_app autoconf${MY_AC_VER} +check_for_app autoheader${MY_AC_VER} +check_for_app automake${MY_AM_VER} +check_for_app aclocal${MY_AM_VER} + +echo "Generating the configure script ..." + +aclocal${MY_AM_VER} +autoconf${MY_AC_VER} +autoheader${MY_AC_VER} +automake${MY_AM_VER} --add-missing --copy 2>/dev/null + +exit 0 diff --git a/build_tools/dahdi_svn_tarball b/build_tools/dahdi_svn_tarball new file mode 100755 index 0000000..7667951 --- /dev/null +++ b/build_tools/dahdi_svn_tarball @@ -0,0 +1,90 @@ +#!/bin/sh + +# upload_dahdi: upload a dahdi tarball to updates.xorcom.com +# + +set -e + +BRANCH_NAME=1.4 +REV=HEAD +DAHDI_BASE=http://svn.digium.com/svn/dahdi +TARBALLS_DIR=$PWD + +me=`basename $0` + +say() { + echo "$me: $@" +} + +usage() { + echo >&2 "$0: Generate snapshot from DAHDI SVN" + echo >&2 ' ($Id$)' + echo >&2 "" + echo >&2 "$0 [-r REV] [-2] [-s]" + echo >&2 "$0 <-h | --help>: This message" + echo >&2 "" + echo >&2 "Options:" + echo >&2 " -2 --dahdi12: Use Asterisk 1.2. Implies -u." + echo >&2 " -r --rev REV: extract xpp-dahdi from this revision ($REV)." + echo >&2 " -s --show: Just show versions. Do nothing" + +} + +opt_showonly=no + +options=`getopt -o 2hr:s --long dahdi12,help,rev:,revision:,show -- "$@"` +if [ $? != 0 ] ; then echo >&2 "Terminating..." ; exit 1 ; fi + +# Note the quotes around `$TEMP': they are essential! +eval set -- "$options" + +while true ; do + case "$1" in + -2|--dahdi12) BRANCH_NAME=1.2;; + -s|--show) opt_showonly=yes ;; + -r|--rev|--revision) REV="$2"; shift ;; + -h|--help) usage; exit 0;; + --) shift ; break ;; + esac + shift; +done + +BRANCH=branches/$BRANCH_NAME +DAHDI_URL=$DAHDI_BASE/$BRANCH + +set -e + +# Get the name of the "previous version" for this release. +# The idea is to look at the latest tag for that branhch. Tags are +# global, and hence we filter tag names by branch name. +# +# Note: this strips any minor version number. +# e.g: if last releast was 1.4.5.1, this will still return 1.4.5 . Here +# we rely on the fact that the revision number will be added. +dahdi_ver=`svn ls -r $REV $DAHDI_BASE/tags | grep "^$BRANCH_NAME" \ + | sed -e "s/\($BRANCH_NAME\.[0-9]\+\)[/.-].*/\1/" \ + | sort -nu -t . -k 3 | tail -n 1` + +real_rev=`svn info -r $REV $DAHDI_URL \ + | awk '/^Last Changed Rev: /{print $4}'` + +ver_full="$dahdi_ver.9.svn.$real_rev" +tar_name="dahdi-$ver_full" +tar_ball_full="$TARBALLS_DIR/$tar_name.tar.gz" + +say "Version: $ver_full (ver: $dahdi_ver, rev: $real_rev)" +say "Tarball: $tar_ball_full" + +if [ "$opt_showonly" = 'yes' ]; then + exit 0; +fi + +DAHDI_CHECKOUT_DIR=`mktemp -d dahdi_checkout_dir_XXXXXX` + +# Package a tarball from the subversion, using 'make dist': +svn export -q -r $REV $DAHDI_URL $DAHDI_CHECKOUT_DIR/$tar_name +echo "$ver_full" >$DAHDI_CHECKOUT_DIR/$tar_name/.version +tar cz -C $DAHDI_CHECKOUT_DIR -f $tar_ball_full $tar_name + +rm -rf $DAHDI_CHECKOUT_DIR + diff --git a/build_tools/dahdi_sysfs_copy b/build_tools/dahdi_sysfs_copy new file mode 100755 index 0000000..3460bb9 --- /dev/null +++ b/build_tools/dahdi_sysfs_copy @@ -0,0 +1,142 @@ +#! /usr/bin/perl +# +# Written by Oron Peled +# Copyright (C) 2012, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +#dahdi_sysfs_copy: Short perl script to copy dahdi related sysfs trees +# into a designated directory. +# +# $Id: $ +# +use strict; +use warnings; + +use File::Path qw(mkpath); +use File::Copy; +use Cwd qw(realpath); + +my $destdir = shift || die "Usage: $0 \n"; + +my %symlinks; +my %walk_ups; +my %inode_cash; + +# Starting points for recursion +my @toplevels = qw( + /sys/bus/dahdi_devices + /sys/bus/astribanks + /sys/class/dahdi + ); + +# Loop prevention (by inode number lookup) +sub seen { + my $ino = shift || die; + my $path = shift || die; + if(defined $inode_cash{$ino}) { + #print STDERR "DEBUG($ino): $path\n"; + return 1; + } + $inode_cash{$ino}++; + return 0; +} + +# Walk up a path and copy readable attributes from any +# directory level. +sub walk_up { + my $path = shift || die; + my $curr = $path; + # Walk up + for (my $curr = $path; $curr; $curr =~ s'/?[^/]+$'') { + my ($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($curr); + next if seen($ino, $curr); # Skip visited directories + # Scan directory + opendir(my $d, $curr) || die "Failed opendir($curr): $!\n"; + my @entries = readdir $d; + foreach my $entry (@entries) { + next if $entry =~ /^[.][.]?$/; + my $file = "$curr/$entry"; + my ($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($file); + # Copy file + if (-f _ && ($mode & 0004)) { # The '-r _' is buggy + copy($file, "$destdir$file") || + die "Failed to copy '$file': $!\n"; + } + } + closedir $d; + } +} + +# Handle a given path (directory,symlink,regular-file) +sub handle_path { + my $path = shift || die; + my ($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($path); + # Save attributes before recursion starts + my $isdir = -d _; + my $islink = -l _; + my $isreadable = $mode & 00004; # The '-r _' was buggy + return if seen($ino, $path); # Loop prevention + my $dest = "$destdir/$path"; + if ($isdir) { + mkpath("$dest"); + scan_directory($path); + } elsif ($islink) { + # We follow links (the seen() protect us from loops) + my $target = readlink($path) || + die "Failed readlink($path): $!\n"; + my $follow = $target; + if ($target !~ m{^/}) { # fix relative symlinks + my $dir = $path; + $dir =~ s,/[^/]*$,,; + $follow = realpath("$dir/$target"); + } + # Save symlink details, so we create them after all + # destination tree (subdirectories, files) is ready + die "Duplicate entry '$dest'\n" if exists $symlinks{$dest}; + $symlinks{$dest} = "$target"; + # Now follow symlink + handle_path($follow); + $walk_ups{$follow}++; + } elsif ($isreadable) { + copy($path, "$dest") || + die "Failed to copy '$path': $!\n"; + } +} + +# Scan a given directory (calling handle_path for recursion) +sub scan_directory { + my $dir = shift || die; + my $entry; + opendir(my $d, $dir) || die "Failed opendir($dir): $!\n"; + my @dirs = readdir $d; + foreach my $entry (@dirs) { + next if $entry =~ /^[.][.]?$/; + handle_path("$dir/$entry"); + } + closedir $d; +} + +# Filter out non-existing toplevels +my @scan = grep { lstat($_) } @toplevels; + +# Recurse all trees, creating subdirectories and copying files +foreach my $path (@scan) { + handle_path($path); +} + +# Now, that all sub-directories were created, we can +# create the wanted symlinks +for my $dest (keys %symlinks) { + my $link = $symlinks{$dest}; + die "Missing link for '$dest'\n" unless defined $link; + unlink $dest if -l $dest; + symlink($link,$dest) || + die "Failed symlink($link,$dest): $!\n"; +} + +# Walk up directories that were symlink destinations +# and fill their attributes +foreach my $dir (keys %walk_ups) { + walk_up($dir); +} diff --git a/build_tools/dump_sys_state b/build_tools/dump_sys_state new file mode 100755 index 0000000..12e864f --- /dev/null +++ b/build_tools/dump_sys_state @@ -0,0 +1,76 @@ +#!/bin/sh + +# dump_sys_state: dump some /sys and /proc files to a directory. +# $Id$ +# +# Written by Tzafrir Cohen +# Copyright (C) 2009, Xorcom +# +# All rights reserved. +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA + +# The DAHDI-perl modules will use such a dump instead of the files from +# the real system if DAHDI_VIRT_TOP is set to the root. +# +# ./build_tools/dump_sys_state my_sys_state +# +# # And then later: +# DAHDI_VIRT_TOP="$PWD/my_sys_state" dahdi_genconf + +mydir=`dirname $0` +dahdi_sysfs_copy="$mydir/dahdi_sysfs_copy" + +# Give usage message on expected texts + +if [ "$#" -ne 0 ]; then + echo >&2 "Usage: $0" + exit 1 +fi + +id="sys_dump.`hostname`_`date +%F_%H.%M.%S`" +tarball="$id.tar.gz" + +tmpdir=`mktemp -td 'dahdi_dump.XXXXXX'` +echo -n >&2 "Creating ... " +trap "[ -d '$tmpdir' ] && rm -rf '$tmpdir'" 0 1 2 15 + +topdir="$tmpdir/$id" + +if [ -r /proc/bus/usb/devices ]; then + mkdir -p "$topdir/proc/bus/usb" + cp -a /proc/bus/usb/devices "$topdir/proc/bus/usb/" +fi + +if [ -d /proc/dahdi ]; then + mkdir -p "$topdir/proc/dahdi" + if find /proc/dahdi -type f >/dev/null; then + cp -a /proc/dahdi/* "$topdir/proc/dahdi/" + fi +fi + +if [ -d /proc/xpp ]; then + mkdir -p "$topdir/proc/xpp" + if find /proc/xpp -type f >/dev/null; then + cp -a /proc/xpp/* "$topdir/proc/xpp/" + find "$topdir/proc/xpp" -type f -name command -exec rm -f '{}' ';' + fi +fi + +"$dahdi_sysfs_copy" "$topdir" +echo -n >&2 "tarball ... " +( cd "$tmpdir" && tar czf - . ) > "$tarball"; +echo >&2 "ready in '$tarball'" diff --git a/build_tools/make_dist b/build_tools/make_dist new file mode 100755 index 0000000..6c9d453 --- /dev/null +++ b/build_tools/make_dist @@ -0,0 +1,26 @@ +#! /bin/sh + +if [ "$#" -ne 2 ]; then + echo >&2 "Usage: $0 " + exit 1 +fi +package="$1" +version="$2" +tarball_prefix="$package-$version" +echo "I: Making dist tarball for $tarball_prefix" +tarball_name="$tarball_prefix.tar.gz" + +tmp_work_dir=".tmp" +tmp_version_dir="$tmp_work_dir/$tarball_prefix" + +if [ "$DESTDIR" != '' ]; then + destdir="$DESTDIR/" +fi +output="$destdir$tarball_name" + +mkdir -p "$tmp_version_dir" +git archive --format tar HEAD | tar xf - -C "$tmp_version_dir" +echo "$version" > "$tmp_version_dir/.version" +tar czf "$output" -C "$tmp_work_dir" "$tarball_prefix" +rm -rf "$tmp_work_dir" +echo "I: tarball is ready: '$output'" diff --git a/build_tools/make_firmware_object.in b/build_tools/make_firmware_object.in new file mode 100755 index 0000000..1c301a4 --- /dev/null +++ b/build_tools/make_firmware_object.in @@ -0,0 +1,11 @@ +#!/bin/sh -e + +# make an object file from a raw binary firmware file +# arguments: +# 1 - firmware file +# 2 - output file + +bfdname=@BDFNAME@ +bfdarch=@BDFARCH@ + +objcopy -I binary ${1} -B ${bfdarch} -O ${bfdname} ${2} --rename-section .data=.rodata,alloc,load,data,contents,readonly diff --git a/build_tools/make_tree b/build_tools/make_tree new file mode 100755 index 0000000..e69de29 diff --git a/build_tools/make_version b/build_tools/make_version new file mode 100755 index 0000000..319842b --- /dev/null +++ b/build_tools/make_version @@ -0,0 +1,122 @@ +#!/bin/sh + +if [ -f ${1}/.version ]; then + cat ${1}/.version +elif [ -f ${1}/.svnrevision ]; then + echo SVN-`cat ${1}/.svnbranch`-r`cat ${1}/.svnrevision` +elif [ -d ${1}/.svn ]; then + PARTS=`LANG=C svn info ${1} | grep URL | awk '{print $2;}' | sed -e s:^.*/svn/${2}/:: | sed -e 's:/: :g'` + BRANCH=0 + TEAM=0 + + REV=`svnversion -c ${1} | cut -d: -f2` + + if [ "${PARTS}" = "trunk" ] + then + echo SVN-'trunk'-r${REV} + exit 0 + fi + + for PART in $PARTS + do + if [ ${BRANCH} != 0 ] + then + RESULT="${RESULT}-${PART}" + break + fi + + if [ ${TEAM} != 0 ] + then + RESULT="${RESULT}-${PART}" + continue + fi + + if [ "${PART}" = "branches" ] + then + BRANCH=1 + RESULT="branch" + continue + fi + + if [ "${PART}" = "tags" ] + then + BRANCH=1 + RESULT="tag" + continue + fi + + if [ "${PART}" = "team" ] + then + TEAM=1 + continue + fi + done + + echo SVN-${RESULT##-}-r${REV} +elif [ -d ${1}/.git ]; then + # If the first log commit messages indicates that this is checked into + # subversion, we'll just use the SVN- form of the revision. + MODIFIED="" + SVN_REV=`git log --pretty=full -1 | grep -F "git-svn-id:" | sed -e "s/.*\@\([^\s]*\)\s.*/\1/g"` + if [ -z "$SVN_REV" ]; then + VERSION=`git describe --tags --dirty=M 2> /dev/null | sed -e "s/^v\([0-9]\)/\1/"` + if [ $? -ne 0 ]; then + if [ "`git ls-files -m | wc -l`" != "0" ]; then + MODIFIED="M" + fi + # Some older versions of git do not support all the above + # options. + VERSION=GIT-`git rev-parse --short --verify HEAD`${MODIFIED} + fi + echo ${VERSION} + else + PARTS=`LANG=C git log --pretty=full | grep -F "git-svn-id:" | head -1 | awk '{print $2;}' | sed -e s:^.*/svn/$2/:: | sed -e 's:/: :g' | sed -e 's/@.*$//g'` + BRANCH=0 + TEAM=0 + + if [ "`git ls-files -m | wc -l`" != "0" ]; then + MODIFIED="M" + fi + + if [ "${PARTS}" = "trunk" ]; then + echo SVN-'trunk'-r${SVN_REV}${MODIFIED} + exit 0 + fi + + for PART in $PARTS + do + if [ ${BRANCH} != 0 ]; then + RESULT="${RESULT}-${PART}" + break + fi + + if [ ${TEAM} != 0 ]; then + RESULT="${RESULT}-${PART}" + continue + fi + + if [ "${PART}" = "branches" ]; then + BRANCH=1 + RESULT="branch" + continue + fi + + if [ "${PART}" = "tags" ]; then + BRANCH=1 + RESULT="tag" + continue + fi + + if [ "${PART}" = "team" ]; then + TEAM=1 + continue + fi + done + + echo SVN-${RESULT##-}-r${SVN_REV}${MODIFIED} + fi +else + # Use the directory information in the absence of any other version + # information + pwd -P +fi diff --git a/build_tools/make_version_c b/build_tools/make_version_c new file mode 100755 index 0000000..7382f3f --- /dev/null +++ b/build_tools/make_version_c @@ -0,0 +1,10 @@ +#!/bin/sh +cat << END +/* + * version.c + * Automatically generated + */ + +const char dahdi_tools_version[] = "DAHDI Tools Version - ${TOOLSVERSION}"; + +END diff --git a/build_tools/menuselect-deps.in b/build_tools/menuselect-deps.in new file mode 100644 index 0000000..e69de29 diff --git a/build_tools/test_kernel_git b/build_tools/test_kernel_git new file mode 100755 index 0000000..59c196d --- /dev/null +++ b/build_tools/test_kernel_git @@ -0,0 +1,80 @@ +#!/bin/sh + +set -e + +GIT_URL=git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git +CONF_FILE=build_tools/git_test.conf + +usage() { + me=`basename $0` + echo "$me: test building Zaptel vs. kernel from git" + echo "Usage:" + echo " $me checkout Pull a kernel version into " + echo " $me update Update (pull) the kernel tree." + echo " $me setver Set the kernel version" + echo " $me test Test-build" + echo "" + echo " $me versions [pattern] List available versions." +} + +# Set a variable in $CONF_FILE +# The format of CONF_FILE is assumed to be: +# VAR=value +# in shell syntax. "value" may be quoted. +# "value should not contain a '|' character. +set_var() { + var="$1" + val="$2" + if grep -q "^$var=" $CONF_FILE 2>/dev/null; then + sed -i -e "s|^$var=.*|$var=\"$val\"|" $CONF_FILE + else + echo "$var=\"$val\"" >>$CONF_FILE + fi +} + +if [ -r "$CONF_FILE" ]; then . "$CONF_FILE"; fi + +if echo "$CONF_FILE" | grep -qv '^/'; then + # make CONF_FILE an absolute path: + CONF_FILE="$PWD/$CONF_FILE" +fi + +command="$1" + +case "$command" in + checkout) + kernel_dir="$2" + cd "$kernel_dir" + git clone $GIT_URL + set_var kernel_dir "$kernel_dir/linux-2.6" + ;; + update) + cd "$kernel_dir" + git pull + ;; + versions) + cd "$kernel_dir" + git tag -l $2 | cut -c2- + ;; + setver) + kernel_ver="$2" + tag="v$kernel_ver" + cd "$kernel_dir" + git-reset --hard "$tag" + make defconfig prepare + set_var kernel_ver "$kernel_ver" + ;; + test) + # you can pass extra parameters to the make command in + # two ways: + # 1. Set th value of MAKE_PARAMS in git_test.conf . + # 2. Any extra command-line parameter. + shift + make KSRC="$kernel_dir" KVERS=$kernel_ver $MAKE_PARAMS "$@" + ;; + *) + echo "$0: no such command $command. Aborting." + usage + exit 1 + ;; +esac diff --git a/build_tools/uninstall-modules b/build_tools/uninstall-modules new file mode 100755 index 0000000..a654c21 --- /dev/null +++ b/build_tools/uninstall-modules @@ -0,0 +1,41 @@ +#!/bin/sh +# uninstall-modules +# +# Remove all the modules passed in on the command line from the modules +# directory. This script is called by the makefile. + +KERNEL_MODULES_DIR=$1 +shift +MODULES="$*" + +usage() { + echo "$0: Used to delete kernel modules from the modules directory." + echo "" + echo "Usage:" + echo " $0 MODULES_BASE_DIR mod1 [mod2 [...]]" + echo "" + echo " MODULES_BASE_DIR - typically /lib/modules/KVERS" + echo " modN - (optionally partial) module name to remove." +} + +if [ -z "$KERNEL_MODULES_DIR" ]; then + echo "Missing kernel module directory." + usage + exit 1; +fi + +if [ -z "$MODULES" ]; then + echo "Missing one or more modules to delete." + usage + exit 1; +fi +for mod in $MODULES; do + BASE=`basename $mod` + for file in `cat $KERNEL_MODULES_DIR/modules.dep | cut -d : -f 1 | grep "$BASE$"`; do + if [ -e "$file" ]; then + #echo "Deleting $file." + rm -f $file + fi + done +done +exit 0 diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..f32079a --- /dev/null +++ b/config.guess @@ -0,0 +1,1526 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. + +timestamp='2008-01-23' + +# This file 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[456]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:[3456]*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T | authenticamd) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..6759825 --- /dev/null +++ b/config.sub @@ -0,0 +1,1658 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. + +timestamp='2008-01-16' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | score \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tile*) + basic_machine=tile-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 0000000..aa23527 --- /dev/null +++ b/configure @@ -0,0 +1,6470 @@ +#! /bin/sh +# From configure.ac Revision. +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for dahdi 2.8.0. +# +# Report bugs to . +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +# +# "dahdi-tools" +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and www.asterisk.org +$0: about your system, including any error possibly output +$0: before this message. Then install a modern shell, or +$0: manually run the script under such a shell if you do +$0: have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='dahdi' +PACKAGE_TARNAME='dahdi' +PACKAGE_VERSION='2.8.0' +PACKAGE_STRING='dahdi 2.8.0' +PACKAGE_BUGREPORT='www.asterisk.org' +PACKAGE_URL='' + +ac_unique_file="dahdi_cfg.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='LTLIBOBJS +LIBOBJS +PPPD_VERSION +ASCIIDOC +USE_SELINUX +PBX_HDLC +PBX_DAHDI23 +PBX_USB +USB_DIR +USB_INCLUDE +USB_LIB +PBX_NEWT +NEWT_DIR +NEWT_INCLUDE +NEWT_LIB +PBX_DAHDI +DAHDI_DIR +DAHDI_INCLUDE +DAHDI_LIB +DAHDI_DECLARATION_AFTER_STATEMENT +DAHDI_DEVMODE +DOWNLOAD +FETCH +WGET +LN +HOSTCC +BDFARCH +BDFNAME +GNU_MAKE +LN_S +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +LD +EGREP +GREP +CPP +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_dev_mode +with_dahdi +with_newt +with_usb +with_selinux +with_ppp +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures dahdi 2.8.0 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/dahdi] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of dahdi 2.8.0:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-dev-mode Turn on developer mode + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-dahdi=PATH use DAHDI files in PATH + --with-newt=PATH use newt files in PATH + --with-usb=PATH use usb files in PATH + --with-selinux enable (with) / disable (without) SELinux + --with-ppp=PATH Use PPP support from PATH + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +dahdi configure 2.8.0 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. + +"dahdi-tools" +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## ------------------------------- ## +## Report this to www.asterisk.org ## +## ------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by dahdi $as_me 2.8.0, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +# check existence of the package + + + + + +ac_default_prefix=/usr +if test ${sysconfdir} = '${prefix}/etc'; then + sysconfdir=/etc +fi +if test ${mandir} = '${prefix}/man'; then + mandir=/usr/share/man +fi + +if test ${localstatedir} = '${prefix}/var'; then + localstatedir=/var +fi + +# specify output header file +ac_config_headers="$ac_config_headers autoconfig.h" + + +# This needs to be before any macros that use the C compiler +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" +if test "x$ac_cv_header_minix_config_h" = xyes; then : + MINIX=yes +else + MINIX= +fi + + + if test "$MINIX" = yes; then + +$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h + + +$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h + + +$as_echo "#define _MINIX 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if ${ac_cv_safe_to_define___extensions__+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# define __EXTENSIONS__ 1 + $ac_includes_default +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_safe_to_define___extensions__=yes +else + ac_cv_safe_to_define___extensions__=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + test $ac_cv_safe_to_define___extensions__ = yes && + $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h + + $as_echo "#define _ALL_SOURCE 1" >>confdefs.h + + $as_echo "#define _GNU_SOURCE 1" >>confdefs.h + + $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h + + $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h + + + + +for ac_header in sys/soundcard.h linux/soundcard.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ld", so it can be a program name with args. +set dummy ${ac_tool_prefix}ld; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LD"; then + ac_cv_prog_LD="$LD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LD="${ac_tool_prefix}ld" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LD=$ac_cv_prog_LD +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LD"; then + ac_ct_LD=$LD + # Extract the first word of "ld", so it can be a program name with args. +set dummy ld; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LD"; then + ac_cv_prog_ac_ct_LD="$ac_ct_LD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LD="ld" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LD=$ac_cv_prog_ac_ct_LD +if test -n "$ac_ct_LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LD" >&5 +$as_echo "$ac_ct_LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LD" = x; then + LD="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LD=$ac_ct_LD + fi +else + LD="$ac_cv_prog_LD" +fi + + +# Checks for programs. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU make" >&5 +$as_echo_n "checking for GNU make... " >&6; } +if ${ac_cv_GNU_MAKE+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_GNU_MAKE='Not Found' ; + ac_cv_GNU_MAKE_VERSION_MAJOR=0 ; + ac_cv_GNU_MAKE_VERSION_MINOR=0 ; + for a in make gmake gnumake ; do + if test -z "$a" ; then continue ; fi ; + if ( sh -c "$a --version" 2> /dev/null | grep GNU 2>&1 > /dev/null ) ; then + ac_cv_GNU_MAKE=$a ; + ac_cv_GNU_MAKE_VERSION_MAJOR=`$ac_cv_GNU_MAKE --version | grep "GNU Make" | cut -f3 -d' ' | cut -f1 -d'.'` + ac_cv_GNU_MAKE_VERSION_MINOR=`$ac_cv_GNU_MAKE --version | grep "GNU Make" | cut -f2 -d'.' | cut -c1-2` + break; + fi + done ; + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_GNU_MAKE" >&5 +$as_echo "$ac_cv_GNU_MAKE" >&6; } ; +if test "x$ac_cv_GNU_MAKE" = "xNot Found" ; then + as_fn_error $? "*** Please install GNU make. It is required to build Asterisk!" "$LINENO" 5 + exit 1 +fi +GNU_MAKE=$ac_cv_GNU_MAKE + + + +test_obj=conftest.o +if ac_fn_c_try_compile "$LINENO"; then : + + BDFNAME=`LANG=C objdump -f $test_obj | grep -e "$test_obj:" | sed "s/.*file format \(.*\)/\1/"` + BDFARCH=`LANG=C objdump -f $test_obj | grep -e "architecture:" | sed "s/.*ture: \(.*\),.*/\1/"` + +fi +rm -f core conftest.err conftest.$ac_objext + + + +# Set the default value of HOSTCC from CC if --host was not provided: +HOSTCC=${HOSTCC:=${CC}} + + +# Extract the first word of "grep", so it can be a program name with args. +set dummy grep; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $GREP in + [\\/]* | ?:[\\/]*) + ac_cv_path_GREP="$GREP" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_GREP="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_GREP" && ac_cv_path_GREP=":" + ;; +esac +fi +GREP=$ac_cv_path_GREP +if test -n "$GREP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GREP" >&5 +$as_echo "$GREP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +# Extract the first word of "sh", so it can be a program name with args. +set dummy sh; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_SHELL+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $SHELL in + [\\/]* | ?:[\\/]*) + ac_cv_path_SHELL="$SHELL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_SHELL="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_SHELL" && ac_cv_path_SHELL=":" + ;; +esac +fi +SHELL=$ac_cv_path_SHELL +if test -n "$SHELL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SHELL" >&5 +$as_echo "$SHELL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +# Extract the first word of "ln", so it can be a program name with args. +set dummy ln; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_LN+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $LN in + [\\/]* | ?:[\\/]*) + ac_cv_path_LN="$LN" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_LN="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_LN" && ac_cv_path_LN=":" + ;; +esac +fi +LN=$ac_cv_path_LN +if test -n "$LN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LN" >&5 +$as_echo "$LN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + +# Extract the first word of "wget", so it can be a program name with args. +set dummy wget; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_WGET+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $WGET in + [\\/]* | ?:[\\/]*) + ac_cv_path_WGET="$WGET" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_WGET="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_WGET" && ac_cv_path_WGET=":" + ;; +esac +fi +WGET=$ac_cv_path_WGET +if test -n "$WGET"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WGET" >&5 +$as_echo "$WGET" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test "${WGET}" != ":" ; then + DOWNLOAD=${WGET} +else + # Extract the first word of "fetch", so it can be a program name with args. +set dummy fetch; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_FETCH+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $FETCH in + [\\/]* | ?:[\\/]*) + ac_cv_path_FETCH="$FETCH" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_FETCH="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_FETCH" && ac_cv_path_FETCH=":" + ;; +esac +fi +FETCH=$ac_cv_path_FETCH +if test -n "$FETCH"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FETCH" >&5 +$as_echo "$FETCH" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + DOWNLOAD=${FETCH} +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Check whether --enable-dev-mode was given. +if test "${enable_dev_mode+set}" = set; then : + enableval=$enable_dev_mode; case "${enableval}" in + y|ye|yes) DAHDI_DEVMODE=yes ;; + n|no) DAHDI_DEVMODE=no ;; + *) as_fn_error $? "bad value ${enableval} for --enable-dev-mode" "$LINENO" 5 ;; + esac +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wdeclaration-after-statement support" >&5 +$as_echo_n "checking for -Wdeclaration-after-statement support... " >&6; } +if $(${CC} -Wdeclaration-after-statement -S -o /dev/null -xc /dev/null > /dev/null 2>&1); then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + DAHDI_DECLARATION_AFTER_STATEMENT=-Wdeclaration-after-statement +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + DAHDI_DECLARATION_AFTER_STATEMENT= +fi + + + + DAHDI_DESCRIP="DAHDI" + DAHDI_OPTION="dahdi" + +# Check whether --with-dahdi was given. +if test "${with_dahdi+set}" = set; then : + withval=$with_dahdi; + case ${withval} in + n|no) + USE_DAHDI=no + ;; + y|ye|yes) + ac_mandatory_list="${ac_mandatory_list} DAHDI" + ;; + *) + DAHDI_DIR="${withval}" + ac_mandatory_list="${ac_mandatory_list} DAHDI" + ;; + esac + +fi + + PBX_DAHDI=0 + + + + + + + NEWT_DESCRIP="newt" + NEWT_OPTION="newt" + +# Check whether --with-newt was given. +if test "${with_newt+set}" = set; then : + withval=$with_newt; + case ${withval} in + n|no) + USE_NEWT=no + ;; + y|ye|yes) + ac_mandatory_list="${ac_mandatory_list} NEWT" + ;; + *) + NEWT_DIR="${withval}" + ac_mandatory_list="${ac_mandatory_list} NEWT" + ;; + esac + +fi + + PBX_NEWT=0 + + + + + + + USB_DESCRIP="usb" + USB_OPTION="usb" + +# Check whether --with-usb was given. +if test "${with_usb+set}" = set; then : + withval=$with_usb; + case ${withval} in + n|no) + USE_USB=no + ;; + y|ye|yes) + ac_mandatory_list="${ac_mandatory_list} USB" + ;; + *) + USB_DIR="${withval}" + ac_mandatory_list="${ac_mandatory_list} USB" + ;; + esac + +fi + + PBX_USB=0 + + + + + + + + if test "x${PBX_DAHDI}" != "x1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DAHDI_CODE in dahdi/user.h" >&5 +$as_echo_n "checking for DAHDI_CODE in dahdi/user.h... " >&6; } + saved_cppflags="${CPPFLAGS}" + if test "x${DAHDI_DIR}" != "x"; then + DAHDI_INCLUDE="-I${DAHDI_DIR}/include" + fi + CPPFLAGS="${CPPFLAGS} ${DAHDI_INCLUDE}" + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include +int +main () +{ +#if defined(DAHDI_CODE) + int foo = 0; + #else + int foo = bar; + #endif + 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + PBX_DAHDI=1 + +$as_echo "#define HAVE_DAHDI 1" >>confdefs.h + + +$as_echo "#define HAVE_DAHDI_VERSION /**/" >>confdefs.h + + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CPPFLAGS="${saved_cppflags}" + fi + + +DAHDI23_DIR="${DAHDI_DIR}" + + if test "x${PBX_DAHDI23}" != "x1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DAHDI_CONFIG_NTTE in dahdi/user.h" >&5 +$as_echo_n "checking for DAHDI_CONFIG_NTTE in dahdi/user.h... " >&6; } + saved_cppflags="${CPPFLAGS}" + if test "x${DAHDI23_DIR}" != "x"; then + DAHDI23_INCLUDE="-I${DAHDI23_DIR}/include" + fi + CPPFLAGS="${CPPFLAGS} ${DAHDI23_INCLUDE}" + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include +int +main () +{ +#if defined(DAHDI_CONFIG_NTTE) + int foo = 0; + #else + int foo = bar; + #endif + 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + PBX_DAHDI23=1 + +$as_echo "#define HAVE_DAHDI23 1" >>confdefs.h + + +$as_echo "#define HAVE_DAHDI23_VERSION /**/" >>confdefs.h + + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CPPFLAGS="${saved_cppflags}" + fi + + + +if test "x${PBX_NEWT}" != "x1" -a "${USE_NEWT}" != "no"; then + pbxlibdir="" + # if --with-NEWT=DIR has been specified, use it. + if test "x${NEWT_DIR}" != "x"; then + if test -d ${NEWT_DIR}/lib; then + pbxlibdir="-L${NEWT_DIR}/lib" + else + pbxlibdir="-L${NEWT_DIR}" + fi + fi + pbxfuncname="newtBell" + if test "x${pbxfuncname}" = "x" ; then # empty lib, assume only headers + AST_NEWT_FOUND=yes + else + as_ac_Lib=`$as_echo "ac_cv_lib_newt_${pbxfuncname}" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lnewt" >&5 +$as_echo_n "checking for ${pbxfuncname} in -lnewt... " >&6; } +if eval \${$as_ac_Lib+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnewt ${pbxlibdir} $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ${pbxfuncname} (); +int +main () +{ +return ${pbxfuncname} (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$as_ac_Lib=yes" +else + eval "$as_ac_Lib=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +eval ac_res=\$$as_ac_Lib + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : + AST_NEWT_FOUND=yes +else + AST_NEWT_FOUND=no +fi + + fi + + # now check for the header. + if test "${AST_NEWT_FOUND}" = "yes"; then + NEWT_LIB="${pbxlibdir} -lnewt " + # if --with-NEWT=DIR has been specified, use it. + if test "x${NEWT_DIR}" != "x"; then + NEWT_INCLUDE="-I${NEWT_DIR}/include" + fi + NEWT_INCLUDE="${NEWT_INCLUDE} " + if test "xnewt.h" = "x" ; then # no header, assume found + NEWT_HEADER_FOUND="1" + else # check for the header + saved_cppflags="${CPPFLAGS}" + CPPFLAGS="${CPPFLAGS} ${NEWT_INCLUDE} " + ac_fn_c_check_header_mongrel "$LINENO" "newt.h" "ac_cv_header_newt_h" "$ac_includes_default" +if test "x$ac_cv_header_newt_h" = xyes; then : + NEWT_HEADER_FOUND=1 +else + NEWT_HEADER_FOUND=0 +fi + + + CPPFLAGS="${saved_cppflags}" + fi + if test "x${NEWT_HEADER_FOUND}" = "x0" ; then + NEWT_LIB="" + NEWT_INCLUDE="" + else + if test "x${pbxfuncname}" = "x" ; then # only checking headers -> no library + NEWT_LIB="" + fi + PBX_NEWT=1 + # XXX don't know how to evaluate the description (third argument) in AC_DEFINE_UNQUOTED + +cat >>confdefs.h <<_ACEOF +#define HAVE_NEWT 1 +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define HAVE_NEWT_VERSION /**/ +_ACEOF + + fi + fi +fi + + +if test "x${PBX_USB}" != "x1" -a "${USE_USB}" != "no"; then + pbxlibdir="" + # if --with-USB=DIR has been specified, use it. + if test "x${USB_DIR}" != "x"; then + if test -d ${USB_DIR}/lib; then + pbxlibdir="-L${USB_DIR}/lib" + else + pbxlibdir="-L${USB_DIR}" + fi + fi + pbxfuncname="usb_init" + if test "x${pbxfuncname}" = "x" ; then # empty lib, assume only headers + AST_USB_FOUND=yes + else + as_ac_Lib=`$as_echo "ac_cv_lib_usb_${pbxfuncname}" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lusb" >&5 +$as_echo_n "checking for ${pbxfuncname} in -lusb... " >&6; } +if eval \${$as_ac_Lib+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lusb ${pbxlibdir} $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ${pbxfuncname} (); +int +main () +{ +return ${pbxfuncname} (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$as_ac_Lib=yes" +else + eval "$as_ac_Lib=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +eval ac_res=\$$as_ac_Lib + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : + AST_USB_FOUND=yes +else + AST_USB_FOUND=no +fi + + fi + + # now check for the header. + if test "${AST_USB_FOUND}" = "yes"; then + USB_LIB="${pbxlibdir} -lusb " + # if --with-USB=DIR has been specified, use it. + if test "x${USB_DIR}" != "x"; then + USB_INCLUDE="-I${USB_DIR}/include" + fi + USB_INCLUDE="${USB_INCLUDE} " + if test "xusb.h" = "x" ; then # no header, assume found + USB_HEADER_FOUND="1" + else # check for the header + saved_cppflags="${CPPFLAGS}" + CPPFLAGS="${CPPFLAGS} ${USB_INCLUDE} " + ac_fn_c_check_header_mongrel "$LINENO" "usb.h" "ac_cv_header_usb_h" "$ac_includes_default" +if test "x$ac_cv_header_usb_h" = xyes; then : + USB_HEADER_FOUND=1 +else + USB_HEADER_FOUND=0 +fi + + + CPPFLAGS="${saved_cppflags}" + fi + if test "x${USB_HEADER_FOUND}" = "x0" ; then + USB_LIB="" + USB_INCLUDE="" + else + if test "x${pbxfuncname}" = "x" ; then # only checking headers -> no library + USB_LIB="" + fi + PBX_USB=1 + # XXX don't know how to evaluate the description (third argument) in AC_DEFINE_UNQUOTED + +cat >>confdefs.h <<_ACEOF +#define HAVE_USB 1 +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define HAVE_USB_VERSION /**/ +_ACEOF + + fi + fi +fi + + +for ac_func in semtimedop +do : + ac_fn_c_check_func "$LINENO" "semtimedop" "ac_cv_func_semtimedop" +if test "x$ac_cv_func_semtimedop" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SEMTIMEDOP 1 +_ACEOF + +fi +done + + +PBX_HDLC=0 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GENERIC_HDLC_VERSION version 4 in linux/hdlc.h" >&5 +$as_echo_n "checking for GENERIC_HDLC_VERSION version 4 in linux/hdlc.h... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include +int +main () +{ +#if defined(GENERIC_HDLC_VERSION) && GENERIC_HDLC_VERSION >= 4 + int foo = 0; + #else + int foo = bar; + #endif + 0 + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + PBX_HDLC=1 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +if test $PBX_HDLC = 0; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GENERIC_HDLC_VERSION version 4 in linux/hdlc/ioctl.h" >&5 +$as_echo_n "checking for GENERIC_HDLC_VERSION version 4 in linux/hdlc/ioctl.h... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include +int +main () +{ +#if defined(GENERIC_HDLC_VERSION) && GENERIC_HDLC_VERSION >= 4 + int foo = 0; + #else + int foo = bar; + #endif + 0 + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + PBX_HDLC=1 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +if test "x${PBX_HDLC}" != "x1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: GENERIC_HDLC_VERSION (version 4) not found, disabling sethdlc." >&5 +$as_echo "$as_me: GENERIC_HDLC_VERSION (version 4) not found, disabling sethdlc." >&6;} +fi + + + + +# Check whether --with-selinux was given. +if test "${with_selinux+set}" = set; then : + withval=$with_selinux; USE_SELINUX=$withval +else + if test ! -x /usr/sbin/sestatus; then + USE_SELINUX=no; + elif /usr/sbin/sestatus | grep "SELinux status:" | grep -q "enabled"; then + USE_SELINUX=yes + fi + + +fi + + + + + +# for asciidoc before ver. 7, the backend must be stated explicitly: +ASCIIDOC='asciidoc' +asciidoc_ver=`asciidoc --version 2>&1 | awk '/^asciidoc /{print $2}' | cut -d. -f 1 | head -n 1` +if test "$asciidoc_ver" != '' && test $asciidoc_ver -lt 7; then + ASCIIDOC="asciidoc -b xhtml" +fi + + + +# Check whether --with-ppp was given. +if test "${with_ppp+set}" = set; then : + withval=$with_ppp; +else + with_ppp=check + +fi + +# somebody will fix that +default_ppp_path=/usr + +case "$with_ppp" in + yes|check) ppp_path="$default_ppp_path";; + no) ppp_path='' ;; + *) ppp_path="$with_ppp" ;; +esac + +level_file="$ppp_path/include/pppd/patchlevel.h" +PPP_VERSION= +if test "$ppp_path" != '' && test -r "$level_file"; then + PPPD_VERSION=`awk -F '"' '/VERSION/ { print $$2; }' $level_file` +fi + +case "$with_ppp" in + check|no) :;; + *) + # If we asked explicitly for ppp support + if test "$PPPD_VERSION" = ''; then + # but have not detected it + as_fn_error $? "failed to find pppd/patchlevel.h: no ppp support." "$LINENO" 5 + fi + ;; +esac + +if test "x${PBX_DAHDI}" != "x1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: ***" >&5 +$as_echo "$as_me: ***" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: *** Building this package requires DAHDI support. *** " >&5 +$as_echo "$as_me: *** Building this package requires DAHDI support. *** " >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: *** Please install the dahdi-linux package. ***" >&5 +$as_echo "$as_me: *** Please install the dahdi-linux package. ***" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: ***" >&5 +$as_echo "$as_me: ***" >&6;} + exit 1 +fi + +if test "x${PBX_DAHDI23}" != "x1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: ***" >&5 +$as_echo "$as_me: ***" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: *** Building this package requires DAHDI support (>= 2.3) *** " >&5 +$as_echo "$as_me: *** Building this package requires DAHDI support (>= 2.3) *** " >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: *** Please install a recent dahdi-linux package. ***" >&5 +$as_echo "$as_me: *** Please install a recent dahdi-linux package. ***" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: ***" >&5 +$as_echo "$as_me: ***" >&6;} + exit 1 +fi + + + +ac_config_files="$ac_config_files makeopts" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by dahdi $as_me 2.8.0, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +dahdi config.status 2.8.0 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "autoconfig.h") CONFIG_HEADERS="$CONFIG_HEADERS autoconfig.h" ;; + "makeopts") CONFIG_FILES="$CONFIG_FILES makeopts" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi + ;; + + + esac + +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: *** dahdi-tools build successfully configured ***" >&5 +$as_echo "$as_me: *** dahdi-tools build successfully configured ***" >&6;} diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..4fa396b --- /dev/null +++ b/configure.ac @@ -0,0 +1,217 @@ +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.59) + +m4_define([TOOLSVERSION], + m4_bpatsubst(m4_esyscmd([build_tools/make_version . dahdi/tools]), + [\([0-9.]*\)\(\w\|\W\)*], + [\1])) +AC_INIT(dahdi, TOOLSVERSION, www.asterisk.org) + +# check existence of the package +AC_CONFIG_SRCDIR([dahdi_cfg.c]) + +AC_COPYRIGHT("dahdi-tools") +AC_REVISION($Revision$) + +ac_default_prefix=/usr +if test ${sysconfdir} = '${prefix}/etc'; then + sysconfdir=/etc +fi +if test ${mandir} = '${prefix}/man'; then + mandir=/usr/share/man +fi + +if test ${localstatedir} = '${prefix}/var'; then + localstatedir=/var +fi + +# specify output header file +AC_CONFIG_HEADER(autoconfig.h) + +# This needs to be before any macros that use the C compiler +AC_GNU_SOURCE + +AC_CHECK_HEADERS([sys/soundcard.h linux/soundcard.h]) + +AC_CHECK_TOOL([LD], [ld]) + +# Checks for programs. +AC_PROG_CC +AC_PROG_CPP +AC_PROG_INSTALL +AC_PROG_LN_S +AST_CHECK_GNU_MAKE + +test_obj=conftest.o +AC_COMPILE_IFELSE(AC_LANG_SOURCE(),[ + BDFNAME=`LANG=C objdump -f $test_obj | grep -e "$test_obj:" | sed "s/.*file format \(.*\)/\1/"` + BDFARCH=`LANG=C objdump -f $test_obj | grep -e "architecture:" | sed "s/.*ture: \(.*\),.*/\1/"` +],[]) +AC_SUBST(BDFNAME) +AC_SUBST(BDFARCH) + +# Set the default value of HOSTCC from CC if --host was not provided: +HOSTCC=${HOSTCC:=${CC}} +AC_SUBST(HOSTCC) + +AC_PATH_PROG([GREP], [grep], :) +AC_PATH_PROG([SHELL], [sh], :) +AC_PATH_PROG([LN], [ln], :) + +AC_PATH_PROG([WGET], [wget], :) +if test "${WGET}" != ":" ; then + DOWNLOAD=${WGET} +else + AC_PATH_PROG([FETCH], [fetch], [:]) + DOWNLOAD=${FETCH} +fi +AC_SUBST(DOWNLOAD) + +AC_LANG(C) + +AC_ARG_ENABLE(dev-mode, + [ --enable-dev-mode Turn on developer mode], + [case "${enableval}" in + y|ye|yes) DAHDI_DEVMODE=yes ;; + n|no) DAHDI_DEVMODE=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-dev-mode) ;; + esac]) +AC_SUBST(DAHDI_DEVMODE) + +AC_MSG_CHECKING(for -Wdeclaration-after-statement support) +if $(${CC} -Wdeclaration-after-statement -S -o /dev/null -xc /dev/null > /dev/null 2>&1); then + AC_MSG_RESULT(yes) + DAHDI_DECLARATION_AFTER_STATEMENT=-Wdeclaration-after-statement +else + AC_MSG_RESULT(no) + DAHDI_DECLARATION_AFTER_STATEMENT= +fi +AC_SUBST(DAHDI_DECLARATION_AFTER_STATEMENT) + +AST_EXT_LIB_SETUP([DAHDI], [DAHDI], [dahdi]) +AST_EXT_LIB_SETUP([NEWT], [newt], [newt]) +AST_EXT_LIB_SETUP([USB], [usb], [usb]) + +AST_C_DEFINE_CHECK([DAHDI], [DAHDI_CODE], [dahdi/user.h]) +DAHDI23_DIR="${DAHDI_DIR}" +AST_C_DEFINE_CHECK([DAHDI23], [DAHDI_CONFIG_NTTE], [dahdi/user.h]) +AST_EXT_LIB_CHECK([NEWT], [newt], [newtBell], [newt.h]) +AST_EXT_LIB_CHECK([USB], [usb], [usb_init], [usb.h]) + +AC_CHECK_FUNCS([semtimedop]) + +PBX_HDLC=0 +AC_MSG_CHECKING([for GENERIC_HDLC_VERSION version 4 in linux/hdlc.h]) +AC_COMPILE_IFELSE( + [ AC_LANG_PROGRAM( [#include ], + [#if defined(GENERIC_HDLC_VERSION) && GENERIC_HDLC_VERSION >= 4 + int foo = 0; + #else + int foo = bar; + #endif + 0])], + [AC_MSG_RESULT(yes) + PBX_HDLC=1], + [AC_MSG_RESULT(no)] +) +if test $PBX_HDLC = 0; then + AC_MSG_CHECKING([for GENERIC_HDLC_VERSION version 4 in linux/hdlc/ioctl.h]) + AC_COMPILE_IFELSE( + [ AC_LANG_PROGRAM( [ + #include + #include ], + [#if defined(GENERIC_HDLC_VERSION) && GENERIC_HDLC_VERSION >= 4 + int foo = 0; + #else + int foo = bar; + #endif + 0])], + [AC_MSG_RESULT(yes) + PBX_HDLC=1], + [AC_MSG_RESULT(no)] + ) +fi + +if test "x${PBX_HDLC}" != "x1"; then + AC_MSG_NOTICE([GENERIC_HDLC_VERSION (version 4) not found, disabling sethdlc.]) +fi + +AC_SUBST(PBX_HDLC) + +AC_ARG_WITH(selinux, + [AS_HELP_STRING([--with-selinux], + [enable (with) / disable (without) SELinux])], + [USE_SELINUX=$withval], + [ if test ! -x /usr/sbin/sestatus; then + USE_SELINUX=no; + elif /usr/sbin/sestatus | grep "SELinux status:" | grep -q "enabled"; then + USE_SELINUX=yes + fi + ] +) + + +AC_SUBST(USE_SELINUX) + +# for asciidoc before ver. 7, the backend must be stated explicitly: +ASCIIDOC='asciidoc' +asciidoc_ver=`asciidoc --version 2>&1 | awk '/^asciidoc /{print $2}' | cut -d. -f 1 | head -n 1` +if test "$asciidoc_ver" != '' && test $asciidoc_ver -lt 7; then + ASCIIDOC="asciidoc -b xhtml" +fi +AC_SUBST(ASCIIDOC) + +AC_ARG_WITH(ppp, + [AS_HELP_STRING([--with-ppp=PATH],[Use PPP support from PATH])], + [], + [with_ppp=check] + ) +# somebody will fix that +default_ppp_path=/usr + +case "$with_ppp" in + yes|check) ppp_path="$default_ppp_path";; + no) ppp_path='' ;; + *) ppp_path="$with_ppp" ;; +esac + +level_file="$ppp_path/include/pppd/patchlevel.h" +PPP_VERSION= +if test "$ppp_path" != '' && test -r "$level_file"; then + PPPD_VERSION=`awk -F '"' '/VERSION/ { print $$2; }' $level_file` +fi + +case "$with_ppp" in + check|no) :;; + *) + # If we asked explicitly for ppp support + if test "$PPPD_VERSION" = ''; then + # but have not detected it + AC_MSG_ERROR(failed to find pppd/patchlevel.h: no ppp support.) + fi + ;; +esac + +if test "x${PBX_DAHDI}" != "x1"; then + AC_MSG_NOTICE([***]) + AC_MSG_NOTICE([*** Building this package requires DAHDI support. *** ]) + AC_MSG_NOTICE([*** Please install the dahdi-linux package. ***]) + AC_MSG_NOTICE([***]) + exit 1 +fi + +if test "x${PBX_DAHDI23}" != "x1"; then + AC_MSG_NOTICE([***]) + AC_MSG_NOTICE([*** Building this package requires DAHDI support (>= 2.3) *** ]) + AC_MSG_NOTICE([*** Please install a recent dahdi-linux package. ***]) + AC_MSG_NOTICE([***]) + exit 1 +fi + +AC_SUBST(PPPD_VERSION) + +AC_CONFIG_FILES([makeopts]) +AC_OUTPUT + +AC_MSG_NOTICE(*** dahdi-tools build successfully configured ***) diff --git a/dahdi-bash-completion b/dahdi-bash-completion new file mode 100644 index 0000000..d98074a --- /dev/null +++ b/dahdi-bash-completion @@ -0,0 +1,133 @@ +# Check for bash +[ -z "$BASH_VERSION" ] && return + +__dahdi_span_assignments() { + local cur prev has_cmd i + COMPREPLY=() + cur=${COMP_WORDS[COMP_CWORD]} + prev=${COMP_WORDS[COMP_CWORD-1]} + + has_cmd=0 + for (( i=0; i < COMP_CWORD; i++)); do + case "${COMP_WORDS[$i]}" in + add | auto | dumpconfig | list | remove) + has_cmd=1 + break + ;; + esac + done + case "$prev" in + -k | --key) COMPREPLY=( $(compgen -W 'devpath hwid location' -- $cur) ) ;; + *) + case "$cur" in + -*) COMPREPLY=( ${COMPREPLY[@]} $(compgen -W \ + '-h -k -n -v --help --key --dry-run --verbose' -- $cur ) ) + ;; + *) + if [ "$has_cmd" = 1 ]; then + COMPREPLY=( ${COMPREPLY[@]} $(shopt -s nullglob; \ + echo /sys/bus/dahdi_devices/devices/* ) ) + else + COMPREPLY=( ${COMPREPLY[@]} $(compgen -W \ + 'add auto dumpconfig list remove' -- $cur) ) + fi + ;; + esac + ;; + esac +} + +complete -F __dahdi_span_assignments dahdi_span_assignments + +__dahdi_span_types() { + local cur prev has_cmd i + COMPREPLY=() + cur=${COMP_WORDS[COMP_CWORD]} + prev=${COMP_WORDS[COMP_CWORD-1]} + + has_cmd=0 + for (( i=0; i < COMP_CWORD; i++)); do + case "${COMP_WORDS[$i]}" in + dumpconfig | list | set) + has_cmd=1 + break + ;; + esac + done + case "$prev" in + -k | --key) COMPREPLY=( $(compgen -W 'devpath hwid location' -- $cur) ) ;; + --line-type) COMPREPLY=( $(compgen -W 'E1 J1 T1' -- $cur) ) ;; + *) + case "$cur" in + -*) COMPREPLY=( ${COMPREPLY[@]} $(compgen -W \ + '-h -k -n -v --help --key --dry-run --line-type --verbose' -- $cur ) ) + ;; + *) + if [ "$has_cmd" = 1 ]; then + # FIXME: check if devices are settable? + COMPREPLY=( ${COMPREPLY[@]} $( \ + grep -l '[EJT]1' /sys/devices/pci0000:00/0000:00:10.4/usb1/1-1/xbus-00/*/spantype 2>/dev/null | sed -e 's|/spantype||') ) + else + COMPREPLY=( ${COMPREPLY[@]} $(compgen -W \ + 'dumpconfig list set' -- $cur) ) + fi + ;; + esac + ;; + esac +} + +complete -F __dahdi_span_types dahdi_span_types + + +__dahdi_genconf() { + local cur + COMPREPLY=() + prev=${COMP_WORDS[COMP_CWORD-1]} + cur=${COMP_WORDS[COMP_CWORD]} + + case "$prev" in + --line-type) COMPREPLY=( $(compgen -W 'E1 J1 T1' -- $cur) ) ;; + *) + case "$cur" in + -*) COMPREPLY+=( $(compgen -W '-F -v -V --freepbx --version --verbose --line-type' -- $cur ) ) ;; + *) + COMPREPLY+=( $(compgen -W "$( perl -e 'my $file = "\u$ARGV[0]"; + # Complete module name. Translate the case of the + # first letter + my @pats = map {"$_/Dahdi/Config/Gen/$file*.pm"} @INC; + foreach (@pats) { + foreach(glob) { + s|.*/||; + s|.pm$||; + s|^(.)|lc($1)|e; + print "$_ " + } + }')" -- $cur ) ) + ;; + esac + ;; + esac +} + +complete -F __dahdi_genconf dahdi_genconf + +__dahdi_cfg() { + local cur prev + COMPREPLY=() + cur=${COMP_WORDS[COMP_CWORD]} + prev=${COMP_WORDS[COMP_CWORD-1]} + + case "$prev" in + -c) COMPREPLY=( $(compgen -f -- $cur) ) ;; + -S) COMPREPLY=( $(ls -d /sys/bus/dahdi_spans/devices/* 2>/dev/null | sed -e 's/.*-//') ) ;; + # FIXME: A similar completion for -C (-) + *) + COMPREPLY=( ${COMPREPLY[@]} $(compgen -W \ + '-c -C -f -h -s -S -t -v ' -- $cur ) ) + ;; + esac +} + +# Disable until -c works properly +#complete -F __dahdi_cfg dahdi_cfg diff --git a/dahdi.init b/dahdi.init new file mode 100755 index 0000000..68420c7 --- /dev/null +++ b/dahdi.init @@ -0,0 +1,343 @@ +#!/bin/sh +# +# dahdi This shell script takes care of loading and unloading \ +# DAHDI Telephony interfaces +# chkconfig: 2345 9 92 +# description: The DAHDI drivers allow you to use your linux \ +# computer to accept incoming data and voice interfaces +# +# config: /etc/dahdi/init.conf + +### BEGIN INIT INFO +# Provides: dahdi +# Required-Start: $local_fs $remote_fs +# Required-Stop: $local_fs $remote_fs +# Should-Start: $network $syslog +# Should-Stop: $network $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: DAHDI kernel modules +# Description: dahdi - load and configure DAHDI modules +### END INIT INFO + +initdir=/etc/init.d + +# Don't edit the following values. Edit /etc/dahdi/init.conf instead. + +DAHDI_CFG=/usr/sbin/dahdi_cfg +DAHDI_CFG_CMD=${DAHDI_CFG_CMD:-"$DAHDI_CFG"} # e.g: for a custom system.conf location + +FXOTUNE=/usr/sbin/fxotune + +# The default syncer Astribank. Usually set automatically to a sane +# value by xpp_sync(1) if you have an Astribank. You can set this to an +# explicit Astribank (e.g: 01). +XPP_SYNC=auto + +# The maximal timeout (seconds) to wait for udevd to finish generating +# device nodes after the modules have loaded and before running dahdi_cfg. +DAHDI_DEV_TIMEOUT=20 + +# A list of modules to unload when stopping. +# All of their dependencies will be unloaded as well. +DAHDI_UNLOAD_MODULES="dahdi" + +# +# Determine which kind of configuration we're using +# +system=redhat # assume redhat +if [ -f /etc/debian_version ]; then + system=debian +fi + +if [ -f /etc/gentoo-release ]; then + system=debian +fi + +if [ -f /etc/SuSE-release -o -f /etc/novell-release ] +then + system=debian +fi + +# Source function library. +if [ $system = redhat ]; then + . $initdir/functions || exit 0 +fi + +DAHDI_MODULES_FILE="/etc/dahdi/modules" + +[ -r /etc/dahdi/init.conf ] && . /etc/dahdi/init.conf + +if [ $system = redhat ]; then + LOCKFILE=/var/lock/subsys/dahdi +fi + +# recursively unload a module and its dependencies, if possible. +# where's modprobe -r when you need it? +# inputs: module to unload. +# returns: the result from +unload_module() { + module="$1" + line=`lsmod 2>/dev/null | grep "^$1 "` + if [ "$line" = '' ]; then return; fi # module was not loaded + + set -- $line + # $1: the original module, $2: size, $3: refcount, $4: deps list + mods=`echo $4 | tr , ' '` + ec_modules="" + # xpp_usb keeps the xpds below busy if an xpp hardware is + # connected. Hence must be removed before them: + case "$module" in xpd_*) mods="xpp_usb $mods";; esac + + for mod in $mods; do + case "$mod" in + dahdi_echocan_*) + ec_modules="$mod $ec_modules" + ;; + *) + # run in a subshell, so it won't step over our vars: + (unload_module $mod) + ;; + esac + done + # Now that all the other dependencies are unloaded, we can unload the + # dahdi_echocan modules. The drivers that register spans may keep + # references on the echocan modules before they are unloaded. + for mod in $ec_modules; do + (unload_module $mod) + done + rmmod $module +} + +unload_modules() { + for module in $DAHDI_UNLOAD_MODULES; do + unload_module $module + done +} + +# In (xpp) hotplug mode, the init script is also executed from the +# hotplug hook. In that case it should not attempt to loade modules. +# +# This function only retunrs false (1) if we're in hotplug mode and +# coming from the hotplug hook script. +hotplug_should_load_modules() { + if [ "$XPP_HOTPLUG_DAHDI" = yes -a "$CALLED_FROM_ATRIBANK_HOOK" != '' ] + then + return 1 + fi + return 0 +} + +# In (xpp) hotplug mode: quit after we loaded modules. +# +# In hotplug mode, the main run should end here, whereas the rest of the +# script should be finished by the instance running from the hook. +# Note that we only get here if there are actually Astribanks on the +# system (otherwise noone will trigger the run of the hotplug hook +# script). +hotplug_exit_after_load() { + if [ "$XPP_HOTPLUG_DAHDI" = yes -a "$CALLED_FROM_ATRIBANK_HOOK" = '' ] + then + exit 0 + fi +} + +# Initialize the Xorcom Astribank (xpp/) using perl utiliites: +xpp_startup() { + if [ "$ASTERISK_SUPPORTS_DAHDI_HOTPLUG" = yes ]; then + aas_param='/sys/module/dahdi/parameters/auto_assign_spans' + aas=`cat "$aas_param" 2>/dev/null` + if [ "$aas" = 0 ]; then + echo 1>&2 "Don't wait for Astribanks (use Asterisk hotplug-support)" + return 0 + fi + fi + # do nothing if there are no astribank devices: + if ! /usr/share/dahdi/waitfor_xpds; then return 0; fi + + hotplug_exit_after_load +} + + +hpec_start() { + # HPEC license found + if ! echo /var/lib/digium/licenses/HPEC-*.lic | grep -v '\*' | grep -q .; then + return + fi + + # dahdihpec_enable not installed in /usr/sbin + if [ ! -f /usr/sbin/dahdihpec_enable ]; then + echo -n "Running dahdihpec_enable: Failed" + echo -n "." + echo " The dahdihpec_enable binary is not installed in /usr/sbin." + return + fi + + # dahdihpec_enable not set executable + if [ ! -x /usr/sbin/dahdihpec_enable ]; then + echo -n "Running dahdihpec_enable: Failed" + echo -n "." + echo " /usr/sbin/dahdihpec_enable is not set as executable." + return + fi + + # dahdihpec_enable properly installed + if [ $system = debian ]; then + echo -n "Running dahdihpec_enable: " + /usr/sbin/dahdihpec_enable 2> /dev/null + elif [ $system = redhat ]; then + action "Running dahdihpec_enable: " /usr/sbin/dahdihpec_enable + fi + if [ $? = 0 ]; then + echo -n "done" + echo "." + else + echo -n "Failed" + echo -n "." + echo " This can be caused if you had already run dahdihpec_enable, or if your HPEC license is no longer valid." + fi +} + +shutdown_dynamic() { + if ! grep -q ' DYN/' /proc/dahdi/* 2>/dev/null; then return; fi + + # we should only get here if we have dynamic spans. Right? + $DAHDI_CFG_CMD -s +} + +load_modules() { + # Some systems, e.g. Debian Lenny, add here -b, which will break + # loading of modules blacklisted in modprobe.d/* + unset MODPROBE_OPTIONS + modules=`sed -e 's/#.*$//' $DAHDI_MODULES_FILE 2>/dev/null` + #if [ "$modules" = '' ]; then + # what? + #fi + echo "Loading DAHDI hardware modules:" + modprobe dahdi + for line in $modules; do + if [ $system = debian ]; then + echo -n " ${line}: " + if modprobe $line 2> /dev/null; then + echo -n "done" + else + echo -n "error" + fi + elif [ $system = redhat ]; then + action " ${line}: " modprobe $line + fi + done + echo "" +} + +# Make sure that either dahdi is loaded or modprobe-able +dahdi_modules_loadable() { + modinfo dahdi >/dev/null 2>&1 || lsmod | grep -q -w ^dahdi +} + +if [ ! -x "$DAHDI_CFG" ]; then + echo "dahdi_cfg not executable" + exit 0 +fi + +RETVAL=0 + +# See how we were called. +case "$1" in + start) + if ! dahdi_modules_loadable; then + echo "No DAHDI modules on the system. Not starting" + exit 0 + fi + if hotplug_should_load_modules; then + load_modules + fi + + TMOUT=$DAHDI_DEV_TIMEOUT # max secs to wait + + while [ ! -d /dev/dahdi ] ; do + sleep 1 + TMOUT=`expr $TMOUT - 1` + if [ $TMOUT -eq 0 ] ; then + echo "Error: missing /dev/dahdi!" + exit 1 + fi + done + + xpp_startup + + # Assign all spans that weren't handled via udev + /etc/dahdi/assigned-spans.conf + /usr/share/dahdi/dahdi_auto_assign_compat + + if [ $system = debian ]; then + echo -n "Running dahdi_cfg: " + $DAHDI_CFG_CMD 2> /dev/null && echo -n "done" + echo "." + elif [ $system = redhat ]; then + action "Running dahdi_cfg: " $DAHDI_CFG_CMD + fi + RETVAL=$? + + if [ "$LOCKFILE" != '' ]; then + [ $RETVAL -eq 0 ] && touch $LOCKFILE + fi + + if [ -x "$FXOTUNE" ] && [ -r /etc/fxotune.conf ]; then + # Allowed to fail if e.g. Asterisk already uses channels: + $FXOTUNE -s || : + fi + + # Do not try to call xpp_sync if there are no Astribank devices + # installed. + if test -e /sys/bus/astribanks; then + # Set the right Astribanks ticker: + LC_ALL=C xpp_sync "$XPP_SYNC" + fi + + hpec_start + ;; + stop) + # Unload drivers + #shutdown_dynamic # FIXME: needs test from someone with dynamic spans + echo -n "Unloading DAHDI hardware modules: " + if unload_modules; then + echo "done" + else + echo "error" + fi + if [ "$LOCKFILE" != '' ]; then + [ $RETVAL -eq 0 ] && rm -f $LOCKFILE + fi + ;; + unload) + unload_modules + ;; + restart|force-reload) + $0 stop + $0 start + ;; + reload) + if [ $system = debian ]; then + echo -n "Rerunning dahdi_cfg: " + $DAHDI_CFG_CMD 2> /dev/null && echo -n "done" + echo "." + elif [ $system = redhat ]; then + action "Rerunning dahdi_cfg: " $DAHDI_CFG_CMD + fi + RETVAL=$? + ;; + status) + if [ -d /proc/dahdi ]; then + /usr/sbin/lsdahdi + RETVAL=0 + else + RETVAL=3 + fi + ;; + *) + echo "Usage: dahdi {start|stop|restart|status|reload|unload}" + exit 1 +esac + +exit $RETVAL + diff --git a/dahdi.rules b/dahdi.rules new file mode 100644 index 0000000..f5eef2e --- /dev/null +++ b/dahdi.rules @@ -0,0 +1,18 @@ + +ACTION!="add", GOTO="dahdi_add_end" + +# DAHDI devices with ownership/permissions for running as non-root +SUBSYSTEM=="dahdi", OWNER="asterisk", GROUP="asterisk", MODE="0660" + +# Backward compat names: /dev/dahdi/ +SUBSYSTEM=="dahdi_channels", SYMLINK+="dahdi/%m" + +# Add persistant names as well +SUBSYSTEM=="dahdi_channels", ATTRS{hardware_id}!="", SYMLINK+="dahdi/devices/%s{hardware_id}/%s{local_spanno}/%n" +SUBSYSTEM=="dahdi_channels", ATTRS{location}!="", SYMLINK+="dahdi/devices/@%s{location}/%s{local_spanno}/%n" + +LABEL="dahdi_add_end" + +# hotplug scripts +SUBSYSTEM=="dahdi_devices", RUN+="%E{DAHDI_TOOLS_ROOTDIR}/usr/share/dahdi/dahdi_handle_device" +SUBSYSTEM=="dahdi_spans", RUN+="%E{DAHDI_TOOLS_ROOTDIR}/usr/share/dahdi/dahdi_span_config" diff --git a/dahdi.xml b/dahdi.xml new file mode 100644 index 0000000..f071f5d --- /dev/null +++ b/dahdi.xml @@ -0,0 +1,26 @@ + + + + + no + + + hdlc + + + + + no + + + + + + + + + + + libnewt + + diff --git a/dahdi_cfg.c b/dahdi_cfg.c new file mode 100644 index 0000000..30add83 --- /dev/null +++ b/dahdi_cfg.c @@ -0,0 +1,1961 @@ +/* + * Configuration program for DAHDI Telephony Interface + * + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "tonezone.h" +#include "dahdi_tools_version.h" + +#define CONFIG_FILENAME "/etc/dahdi/system.conf" +#define MASTER_DEVICE "/dev/dahdi/ctl" + +#define NUM_SPANS DAHDI_MAX_SPANS + +#define NUM_TONES 15 + +/*! A sanity check for the timing parameter of the span. + * + * Note that each driver using it is still responsible for validating + * that value. + */ +#define MAX_TIMING 255 + +/* Assume no more than 1024 dynamics */ +#define NUM_DYNAMIC 1024 + +static int lineno=0; + +static FILE *cf; + +static char *filename=CONFIG_FILENAME; + +int rxtones[NUM_TONES + 1],rxtags[NUM_TONES + 1],txtones[NUM_TONES + 1]; +int bursttime = 0, debouncetime = 0, invertcor = 0, exttone = 0, corthresh = 0; +int txgain = 0, rxgain = 0, deemp = 0, preemp = 0; + +int corthreshes[] = {3125,6250,9375,12500,15625,18750,21875,25000,0} ; + +static int toneindex = 1; + +#define DEBUG_READER (1 << 0) +#define DEBUG_PARSER (1 << 1) +#define DEBUG_APPLY (1 << 2) +static int debug = 0; + +static int errcnt = 0; + +static int deftonezone = -1; + +static struct dahdi_lineconfig lc[DAHDI_MAX_SPANS]; + +static struct dahdi_chanconfig cc[DAHDI_MAX_CHANNELS]; + +static int current_span = 0; +static int only_span = 0; +static int restrict_channels = 0; +static int selected_channels[DAHDI_MAX_CHANNELS]; +static int chan2span[DAHDI_MAX_CHANNELS]; +static int declared_spans[DAHDI_MAX_SPANS]; + +static struct dahdi_attach_echocan ae[DAHDI_MAX_CHANNELS]; + +static struct dahdi_dynamic_span zds[NUM_DYNAMIC]; + +static const char *sig[DAHDI_MAX_CHANNELS]; /* Signalling */ + +static int slineno[DAHDI_MAX_CHANNELS]; /* Line number where signalling specified */ + +static int fiftysixkhdlc[DAHDI_MAX_CHANNELS]; + +static int spans=0; + +static int dry_run = 0; + +static int verbose = 0; + +static int force = 0; + +static int stopmode = 0; + +static int numdynamic = 0; + +static char zonestoload[DAHDI_TONE_ZONE_MAX][10]; + +static int numzones = 0; + +static int fd = -1; + +static const char *lbostr[] = { +"0 db (CSU)/0-133 feet (DSX-1)", +"133-266 feet (DSX-1)", +"266-399 feet (DSX-1)", +"399-533 feet (DSX-1)", +"533-655 feet (DSX-1)", +"-7.5db (CSU)", +"-15db (CSU)", +"-22.5db (CSU)" +}; + +static const char *laws[] = { + "Default", + "Mu-law", + "A-law" +}; + +static bool _are_all_spans_assigned(const char *device_path) +{ + char attribute[1024]; + int res; + FILE *fp; + int span_count; + DIR *dirp; + struct dirent *dirent; + + snprintf(attribute, sizeof(attribute) - 1, + "%s/span_count", device_path); + fp = fopen(attribute, "r"); + if (NULL == fp) { + fprintf(stderr, "Failed to open '%s'.\n", attribute); + return false; + } + res = fscanf(fp, "%d", &span_count); + fclose(fp); + + if (EOF == res) { + fprintf(stderr, "Failed to read '%s'.\n", attribute); + return false; + } + + dirp = opendir(device_path); + while (span_count) { + dirent = readdir(dirp); + if (NULL == dirent) + break; + if (!strncmp("span-", dirent->d_name, 5)) { + --span_count; + } + } + closedir(dirp); + return (span_count > 0) ? false : true; +} + +/** + * are_all_spans_assigned - Look in sysfs to see if all spans for a device are assigned. + * + * Returns true if there are $span_count child spans of all devices, or false + * otherwise. + */ +static bool are_all_spans_assigned(void) +{ + DIR *dirp; + struct dirent *dirent; + bool res = true; + char device_path[1024]; + + dirp = opendir("/sys/bus/dahdi_devices/devices"); + if (!dirp) { + /* If we cannot open dahdi_devices, either dahdi isn't loaded, + * or we're using an older version of DAHDI that doesn't use + * sysfs. */ + return true; + } + + while (true && res) { + + dirent = readdir(dirp); + if (NULL == dirent) + break; + + if (!strcmp(dirent->d_name, ".") || + !strcmp(dirent->d_name, "..")) + continue; + + snprintf(device_path, sizeof(device_path)-1, + "/sys/bus/dahdi_devices/devices/%s", dirent->d_name); + res = _are_all_spans_assigned(device_path); + } + + closedir(dirp); + errno = 0; + return res; +} + +static bool wait_for_all_spans_assigned(unsigned long timeout_sec) +{ + bool all_assigned = are_all_spans_assigned(); + unsigned int timeout = 10*timeout_sec; + + while (!all_assigned && --timeout) { + usleep(100000); + all_assigned = are_all_spans_assigned(); + } + + return all_assigned; +} + +static const char *sigtype_to_str(const int sig) +{ + switch (sig) { + case 0: + return "Unused"; + case DAHDI_SIG_EM: + return "E & M"; + case DAHDI_SIG_EM_E1: + return "E & M E1"; + case DAHDI_SIG_FXSLS: + return "FXS Loopstart"; + case DAHDI_SIG_FXSGS: + return "FXS Groundstart"; + case DAHDI_SIG_FXSKS: + return "FXS Kewlstart"; + case DAHDI_SIG_FXOLS: + return "FXO Loopstart"; + case DAHDI_SIG_FXOGS: + return "FXO Groundstart"; + case DAHDI_SIG_FXOKS: + return "FXO Kewlstart"; + case DAHDI_SIG_CAS: + return "CAS / User"; + case DAHDI_SIG_DACS: + return "DACS"; + case DAHDI_SIG_DACS_RBS: + return "DACS w/RBS"; + case DAHDI_SIG_CLEAR: + return "Clear channel"; + case DAHDI_SIG_SLAVE: + return "Slave channel"; + case DAHDI_SIG_HDLCRAW: + return "Raw HDLC"; + case DAHDI_SIG_HDLCNET: + return "Network HDLC"; + case DAHDI_SIG_HDLCFCS: + return "HDLC with FCS check"; + case DAHDI_SIG_HARDHDLC: + return "Hardware assisted D-channel"; + case DAHDI_SIG_MTP2: + return "MTP2"; + default: + return "Unknown"; + } +} + +static void clear_fields() +{ + + memset(rxtones,0,sizeof(rxtones)); + memset(rxtags,0,sizeof(rxtags)); + memset(txtones,0,sizeof(txtones)); + bursttime = 0; + debouncetime = 0; + invertcor = 0; + exttone = 0; + txgain = 0; + rxgain = 0; + deemp = 0; + preemp = 0; +} + +static int error(char *fmt, ...) __attribute__ ((format(printf, 1, 2))); + +static int error(char *fmt, ...) +{ + int res; + static int shown=0; + va_list ap; + if (!shown) { + fprintf(stderr, "Notice: Configuration file is %s\n", filename); + shown++; + } + res = fprintf(stderr, "line %d: ", lineno); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + errcnt++; + return res; +} + +static char *trim(char *buf) +{ + size_t len; + + while (*buf && (*buf < 33)) { + buf++; + } + + len = strlen(buf); + + while (len && buf[len-1] < 33) { + buf[--len] = '\0'; + } + + return buf; +} + +static int skip_channel(int x) +{ + int spanno = chan2span[x]; + + if (restrict_channels) { + if (!selected_channels[x]) + return 1; + /* sanity check */ + if (only_span) { + if (spanno != 0 && only_span != spanno) { + fprintf(stderr, + "Only span %d. Skip selected channel %d from span %d\n", + only_span, x, spanno); + return 1; + } + } + } else { + if (only_span && !declared_spans[only_span]) { + fprintf(stderr, + "Error: analog span %d given to '-S', without '-C' restriction.\n", + only_span); + exit(1); + } + if (only_span && only_span != spanno) + return 1; + } + return 0; +} + +static int parseargs(char *input, char *output[], int maxargs, char sep) +{ + char *c; + int pos=0; + c = input; + output[pos++] = c; + while(*c) { + while(*c && (*c != sep)) c++; + if (*c) { + *c = '\0'; + c++; + while(*c && (*c < 33)) c++; + if (*c) { + if (pos >= maxargs) + return -1; + output[pos] = c; + trim(output[pos]); + pos++; + output[pos] = NULL; + /* Return error if we have too many */ + } else + return pos; + } + } + return pos; +} + +int dspanconfig(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int chans; + int timing; + res = parseargs(args, realargs, 4, ','); + if (res != 4) { + error("Incorrect number of arguments to 'dynamic' (should be ,
,, )\n"); + return -1; + } + res = sscanf(realargs[2], "%d", &chans); + if ((res == 1) && (chans < 1)) + res = -1; + if (res != 1) { + error("Invalid number of channels '%s', should be a number > 0.\n", realargs[2]); + return -1; + } + + res = sscanf(realargs[3], "%d", &timing); + if ((res == 1) && (timing < 0)) + res = -1; + if (res != 1) { + error("Invalid timing '%s', should be a number > 0.\n", realargs[3]); + return -1; + } + + + dahdi_copy_string(zds[numdynamic].driver, realargs[0], sizeof(zds[numdynamic].driver)); + dahdi_copy_string(zds[numdynamic].addr, realargs[1], sizeof(zds[numdynamic].addr)); + zds[numdynamic].numchans = chans; + zds[numdynamic].timing = timing; + + numdynamic++; + return 0; +} + +int spanconfig(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int argc; + int span; + int timing; + int i; + argc = res = parseargs(args, realargs, 9, ','); + if ((res < 5) || (res > 9)) { + error("Incorrect number of arguments to 'span' (should be ,,,,[, crc4 | yellow [, yellow]])\n"); + return -1; + } + res = sscanf(realargs[0], "%d", &span); + if (res != 1) { + error("Span number should be a valid span number, not '%s'\n", realargs[0]); + return -1; + } + current_span = span; + declared_spans[span] = 1; + res = sscanf(realargs[1], "%d", &timing); + if ((res != 1) || (timing < 0) || (timing > MAX_TIMING)) { + error("Timing should be a number from 0 to %d, not '%s'\n", + MAX_TIMING, realargs[1]); + return -1; + } + res = sscanf(realargs[2], "%d", &lc[spans].lbo); + if (res != 1) { + error("Line build-out (LBO) should be a number from 0 to 7 (usually 0) not '%s'\n", realargs[2]); + return -1; + } + if ((lc[spans].lbo < 0) || (lc[spans].lbo > 7)) { + error("Line build-out should be in the range 0 to 7, not %d\n", lc[spans].lbo); + return -1; + } + if (!strcasecmp(realargs[3], "d4")) { + lc[spans].lineconfig |= DAHDI_CONFIG_D4; + lc[spans].lineconfig &= ~DAHDI_CONFIG_ESF; + lc[spans].lineconfig &= ~DAHDI_CONFIG_CCS; + } else if (!strcasecmp(realargs[3], "esf")) { + lc[spans].lineconfig |= DAHDI_CONFIG_ESF; + lc[spans].lineconfig &= ~DAHDI_CONFIG_D4; + lc[spans].lineconfig &= ~DAHDI_CONFIG_CCS; + } else if (!strcasecmp(realargs[3], "ccs")) { + lc[spans].lineconfig |= DAHDI_CONFIG_CCS; + lc[spans].lineconfig &= ~(DAHDI_CONFIG_ESF | DAHDI_CONFIG_D4); + } else if (!strcasecmp(realargs[3], "cas")) { + lc[spans].lineconfig &= ~DAHDI_CONFIG_CCS; + lc[spans].lineconfig &= ~(DAHDI_CONFIG_ESF | DAHDI_CONFIG_D4); + } else { + error("Framing(T1)/Signalling(E1) must be one of 'd4', 'esf', 'cas' or 'ccs', not '%s'\n", realargs[3]); + return -1; + } + if (!strcasecmp(realargs[4], "ami")) { + lc[spans].lineconfig &= ~(DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_HDB3); + lc[spans].lineconfig |= DAHDI_CONFIG_AMI; + } else if (!strcasecmp(realargs[4], "b8zs")) { + lc[spans].lineconfig |= DAHDI_CONFIG_B8ZS; + lc[spans].lineconfig &= ~(DAHDI_CONFIG_AMI | DAHDI_CONFIG_HDB3); + } else if (!strcasecmp(realargs[4], "hdb3")) { + lc[spans].lineconfig |= DAHDI_CONFIG_HDB3; + lc[spans].lineconfig &= ~(DAHDI_CONFIG_AMI | DAHDI_CONFIG_B8ZS); + } else { + error("Coding must be one of 'ami', 'b8zs' or 'hdb3', not '%s'\n", realargs[4]); + return -1; + } + for (i = 5; i < argc; i++) { + if (!strcasecmp(realargs[i], "yellow")) + lc[spans].lineconfig |= DAHDI_CONFIG_NOTOPEN; + else if (!strcasecmp(realargs[i], "crc4")) + lc[spans].lineconfig |= DAHDI_CONFIG_CRC4; + else if (!strcasecmp(realargs[i], "nt")) + lc[spans].lineconfig |= DAHDI_CONFIG_NTTE; + else if (!strcasecmp(realargs[i], "te")) + lc[spans].lineconfig &= ~DAHDI_CONFIG_NTTE; + else if (!strcasecmp(realargs[i], "term")) + lc[spans].lineconfig |= DAHDI_CONFIG_TERM; + else { + error("Remaining arguments may be any of: 'yellow', 'crc4', 'nt', 'te', 'term', not '%s'\n", realargs[i]); + return -1; + } + + } + lc[spans].span = span; + lc[spans].sync = timing; + /* Valid span */ + spans++; + return 0; +} + +int apply_channels(int chans[], char *argstr) +{ + char *args[DAHDI_MAX_CHANNELS+1]; + char *range[3]; + int res,x, res2,y; + int chan; + int start, finish; + char argcopy[256]; + res = parseargs(argstr, args, DAHDI_MAX_CHANNELS, ','); + if (res < 0) { + error("Too many arguments... Max is %d\n", DAHDI_MAX_CHANNELS); + return -1; + } + for (x=0;x-.\n", args[x]); + return -1; + } + res2 =sscanf(range[0], "%d", &start); + if (res2 != 1) { + error("Syntax error. Start of range '%s' should be a number from 1 to %d\n", args[x], DAHDI_MAX_CHANNELS - 1); + return -1; + } else if ((start < 1) || (start >= DAHDI_MAX_CHANNELS)) { + error("Start of range '%s' must be between 1 and %d (not '%d')\n", args[x], DAHDI_MAX_CHANNELS - 1, start); + return -1; + } + res2 =sscanf(range[1], "%d", &finish); + if (res2 != 1) { + error("Syntax error. End of range '%s' should be a number from 1 to %d\n", args[x], DAHDI_MAX_CHANNELS - 1); + return -1; + } else if ((finish < 1) || (finish >= DAHDI_MAX_CHANNELS)) { + error("end of range '%s' must be between 1 and %d (not '%d')\n", args[x], DAHDI_MAX_CHANNELS - 1, finish); + return -1; + } + if (start > finish) { + error("Range '%s' should start before it ends\n", args[x]); + return -1; + } + for (y=start;y<=finish;y++) + chans[y]=1; + } else { + /* It's a single channel */ + res2 =sscanf(args[x], "%d", &chan); + if (res2 != 1) { + error("Syntax error. Channel should be a number from 1 to %d, not '%s'\n", DAHDI_MAX_CHANNELS - 1, args[x]); + return -1; + } else if ((chan < 1) || (chan >= DAHDI_MAX_CHANNELS)) { + error("Channel must be between 1 and %d (not '%d')\n", DAHDI_MAX_CHANNELS - 1, chan); + return -1; + } + chans[chan]=1; + } + } + return res; +} + +int parse_idle(int *i, char *s) +{ + char a,b,c,d; + if (s) { + if (sscanf(s, "%c%c%c%c", &a,&b,&c,&d) == 4) { + if (((a == '0') || (a == '1')) && ((b == '0') || (b == '1')) && ((c == '0') || (c == '1')) && ((d == '0') || (d == '1'))) { + *i = 0; + if (a == '1') + *i |= DAHDI_ABIT; + if (b == '1') + *i |= DAHDI_BBIT; + if (c == '1') + *i |= DAHDI_CBIT; + if (d == '1') + *i |= DAHDI_DBIT; + return 0; + } + } + } + error("CAS Signalling requires idle definition in the form ':xxxx' at the end of the channel definition, where xxxx represent the a, b, c, and d bits\n"); + return -1; +} + +static int parse_channel(char *channel, int *startchan) +{ + if (!channel || (sscanf(channel, "%d", startchan) != 1) || + (*startchan < 1)) { + error("DACS requires a starting channel in the form ':x' where x is the channel\n"); + return -1; + } + return 0; +} + +static int chanconfig(char *keyword, char *args) +{ + int chans[DAHDI_MAX_CHANNELS]; + int res = 0; + int x; + int master=0; + int dacschan = 0; + char *idle; + int is_digital; + bzero(chans, sizeof(chans)); + strtok(args, ":"); + idle = strtok(NULL, ":"); + if (!strcasecmp(keyword, "dacs") || !strcasecmp(keyword, "dacsrbs")) { + res = parse_channel(idle, &dacschan); + } + if (!res) + res = apply_channels(chans, args); + if (res <= 0) + return -1; + for (x=1;x= DAHDI_TONE_ZONE_MAX) { + error("Too many tone zones specified\n"); + return 0; + } + dahdi_copy_string(zonestoload[numzones++], args, sizeof(zonestoload[0])); + return 0; +} + +static int defaultzone(char *keyword, char *args) +{ + struct tone_zone *z; + if (!(z = tone_zone_find(args))) { + error("No such tone zone known: %s\n", args); + return 0; + } + deftonezone = z->zone; + return 0; +} + +#if 0 +static int unimplemented(char *keyword, char *args) +{ + fprintf(stderr, "Warning: '%s' is not yet implemented\n", keyword); + return 0; +} +#endif + + +/* Radio functions */ + +int ctcss(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int rxtone; + int rxtag; + int txtone; + int isdcs = 0; + res = parseargs(args, realargs, 3, ','); + if (res != 3) { + error("Incorrect number of arguments to 'ctcss' (should be ,,)\n"); + return -1; + } + res = sscanf(realargs[0], "%d", &rxtone); + if ((res == 1) && (rxtone < 1)) + res = -1; + if (res != 1) { + error("Invalid rxtone '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + res = sscanf(realargs[1], "%d", &rxtag); + if ((res == 1) && (rxtag < 0)) + res = -1; + if (res != 1) { + error("Invalid rxtag '%s', should be a number > 0.\n", realargs[1]); + return -1; + } + if ((*realargs[2] == 'D') || (*realargs[2] == 'd')) + { + realargs[2]++; + isdcs = 0x8000; + } + res = sscanf(realargs[2], "%d", &txtone); + if ((res == 1) && (rxtag < 0)) + res = -1; + if (res != 1) { + error("Invalid txtone '%s', should be a number > 0.\n", realargs[2]); + return -1; + } + + if (toneindex >= NUM_TONES) + { + error("Cannot specify more then %d CTCSS tones\n",NUM_TONES); + return -1; + } + rxtones[toneindex] = rxtone; + rxtags[toneindex] = rxtag; + txtones[toneindex] = txtone | isdcs; + toneindex++; + return 0; +} + +int dcsrx(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int rxtone; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'dcsrx' (should be )\n"); + return -1; + } + res = sscanf(realargs[0], "%d", &rxtone); + if ((res == 1) && (rxtone < 1)) + res = -1; + if (res != 1) { + error("Invalid rxtone '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + + rxtones[0] = rxtone; + return 0; +} + +int tx(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int txtone; + int isdcs = 0; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'tx' (should be )\n"); + return -1; + } + if ((*realargs[0] == 'D') || (*realargs[0] == 'd')) + { + realargs[0]++; + isdcs = 0x8000; + } + res = sscanf(realargs[0], "%d", &txtone); + if ((res == 1) && (txtone < 1)) + res = -1; + if (res != 1) { + error("Invalid tx (tone) '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + + txtones[0] = txtone | isdcs; + return 0; +} + +int debounce_time(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int val; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'debouncetime' (should be )\n"); + return -1; + } + res = sscanf(realargs[0], "%d", &val); + if ((res == 1) && (val < 1)) + res = -1; + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + + debouncetime = val; + return 0; +} + +int burst_time(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int val; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'bursttime' (should be )\n"); + return -1; + } + res = sscanf(realargs[0], "%d", &val); + if ((res == 1) && (val < 1)) + res = -1; + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + + bursttime = val; + return 0; +} + +int tx_gain(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int val; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'txgain' (should be )\n"); + return -1; + } + res = sscanf(realargs[0], "%d", &val); + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + + txgain = val; + return 0; +} + +int rx_gain(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int val; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'rxgain' (should be )\n"); + return -1; + } + res = sscanf(realargs[0], "%d", &val); + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + + rxgain = val; + return 0; +} + +int de_emp(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int val; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'de-emp' (should be )\n"); + return -1; + } + res = sscanf(realargs[0], "%d", &val); + if ((res == 1) && (val < 1)) + res = -1; + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + + deemp = val; + return 0; +} + +int pre_emp(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int val; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'pre_emp' (should be )\n"); + return -1; + } + res = sscanf(realargs[0], "%d", &val); + if ((res == 1) && (val < 1)) + res = -1; + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + + preemp = val; + return 0; +} + +int invert_cor(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int val; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'invertcor' (should be )\n"); + return -1; + } + if ((*realargs[0] == 'y') || (*realargs[0] == 'Y')) val = 1; + else if ((*realargs[0] == 'n') || (*realargs[0] == 'N')) val = 0; + else + { + res = sscanf(realargs[0], "%d", &val); + if ((res == 1) && (val < 0)) + res = -1; + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + } + invertcor = (val > 0); + return 0; +} + +int ext_tone(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int val; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'exttone' (should be )\n"); + return -1; + } + if ((*realargs[0] == 'y') || (*realargs[0] == 'Y')) val = 1; + else if ((*realargs[0] == 'n') || (*realargs[0] == 'N')) val = 0; + else if ((*realargs[0] == 'i') || (*realargs[0] == 'I')) val = 2; + else + { + res = sscanf(realargs[0], "%d", &val); + if ((res == 1) && (val < 0)) + res = -1; + if (val > 2) res = -1; + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + } + exttone = val; + return 0; +} + +int cor_thresh(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int val; + int x = 0; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'corthresh' (should be )\n"); + return -1; + } + res = sscanf(realargs[0], "%d", &val); + if ((res == 1) && (val < 1)) + res = -1; + for(x = 0; corthreshes[x]; x++) + { + if (corthreshes[x] == val) break; + } + if (!corthreshes[x]) res = -1; + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + corthresh = x + 1; + return 0; +} + +static int rad_chanconfig(char *keyword, char *args) +{ + int chans[DAHDI_MAX_CHANNELS]; + int res = 0; + int x,i,n; + struct dahdi_radio_param p; + int chanfd; + + toneindex = 1; + bzero(chans, sizeof(chans)); + res = apply_channels(chans, args); + if (res <= 0) + return -1; + for (x=1;x 1) { + printf("\nChannel map:\n\n"); + for (x=1;x -- Use instead of " CONFIG_FILENAME "\n" + " -d [level] -- Generate debugging output. (Default level is 1.)\n" + " -f -- Always reconfigure every channel\n" + " -h -- Generate this help statement\n" + " -s -- Shutdown spans only\n" + " -t -- Test mode only, do not apply\n" + " -C -- Only configure specified channels\n" + " -S -- Only configure specified span\n" + " -v -- Verbose (more -v's means more verbose)\n" + ,c); + exit(exitcode); +} + +static int chan_restrict(char *str) +{ + if (apply_channels(selected_channels, str) < 0) + return 0; + restrict_channels = 1; + return 1; +} + +static int span_restrict(char *str) +{ + long spanno; + char *endptr; + + spanno = strtol(str, &endptr, 10); + if (endptr == str) { + fprintf(stderr, "Missing valid span number after '-S'\n"); + return 0; + } + if (*endptr != '\0') { + fprintf(stderr, "Extra garbage after span number in '-S'\n"); + return 0; + } + only_span = spanno; + return 1; +} + +static const char *SEM_NAME = "dahdi_cfg"; +static sem_t *lock = SEM_FAILED; + +static void signal_handler(int signal) +{ + if (SEM_FAILED != lock) { + sem_unlink(SEM_NAME); + } + /* The default handler should have been restored before this handler was + * called, so we can let the "normal" processing finish the cleanup. */ + raise(signal); +} + +int main(int argc, char *argv[]) +{ + int c; + char *buf; + char *key, *value; + int x,found; + int exit_code = 0; + struct sigaction act; + + while((c = getopt(argc, argv, "fthc:vsd::C:S:")) != -1) { + switch(c) { + case 'c': + filename=optarg; + break; + case 'h': + usage(argv[0], 0); + break; + case '?': + usage(argv[0], 1); + break; + case 'v': + verbose++; + break; + case 'f': + force++; + break; + case 't': + dry_run = 1; + break; + case 's': + stopmode = 1; + break; + case 'C': + if (!chan_restrict(optarg)) + usage(argv[0], 1); + break; + case 'S': + if (!span_restrict(optarg)) + usage(argv[0], 1); + break; + case 'd': + if (optarg) + debug = atoi(optarg); + else + debug = 1; + break; + } + } + + if (verbose) { + fprintf(stderr, "%s\n", dahdi_tools_version); + } + + if (!restrict_channels && !only_span) { + bool all_assigned = wait_for_all_spans_assigned(5); + + if (!all_assigned) { + fprintf(stderr, + "Timeout waiting for all spans to be assigned.\n"); + } + } + + if (fd == -1) fd = open(MASTER_DEVICE, O_RDWR); + if (fd < 0) { + error("Unable to open master device '%s'\n", MASTER_DEVICE); + goto finish; + } + if (strcmp(filename, "-") == 0) + cf = fdopen(STDIN_FILENO, "r"); + else + cf = fopen(filename, "r"); + if (cf) { + while((buf = readline())) { + if (*buf == 10) /* skip new line */ + continue; + + if (debug & DEBUG_READER) + fprintf(stderr, "Line %d: %s\n", lineno, buf); + + if ((value = strchr(buf, '='))) { + *value++ = '\0'; + value = trim(value); + key = trim(buf); + } + + if (!value || !*value || !*key) { + error("Syntax error. Should be =\n"); + continue; + } + + if (debug & DEBUG_PARSER) + fprintf(stderr, "Keyword: [%s], Value: [%s]\n", key, value); + + found = 0; + for (x = 0; x < sizeof(handlers) / sizeof(handlers[0]); x++) { + if (!strcasecmp(key, handlers[x].keyword)) { + found++; + handlers[x].func(key, value); + break; + } + } + + if (!found) + error("Unknown keyword '%s'\n", key); + } + if (debug & DEBUG_READER) + fprintf(stderr, "\n"); + /* fclose(cf); // causes seg fault (double free) */ + } else { + error("Unable to open configuration file '%s'\n", filename); + } + +finish: + if (errcnt) { + fprintf(stderr, "\n%d error(s) detected\n\n", errcnt); + exit(1); + } + if (verbose) { + printconfig(fd); + } + + if (dry_run) + exit(0); + + if (debug & DEBUG_APPLY) { + printf("About to open Master device\n"); + fflush(stdout); + } + + sigemptyset(&act.sa_mask); + act.sa_handler = signal_handler; + act.sa_flags = SA_RESETHAND; + + if (sigaction(SIGTERM, &act, NULL) == -1) { + perror("Failed to install SIGTERM handler."); + exit(1); + } + if (sigaction(SIGINT, &act, NULL) == -1) { + perror("Failed to install SIGINT handler."); + exit(1); + } + + lock = sem_open(SEM_NAME, O_CREAT, O_RDWR, 1); + if (SEM_FAILED == lock) { + perror("Unable to create 'dahdi_cfg' mutex"); + exit_code = 1; + goto release_sem; + } + + if (-1 == sem_wait(lock)) { + perror("Failed to wait for 'dahdi_cfg' mutex"); + exit_code = 1; + goto unlink_sem; + } + + if (!restrict_channels && !only_span) { + for (x=0;x> 16; + + if (cc[x].sigtype != current_state.sigtype) { + needupdate++; + if (verbose > 1) + printf("Changing signalling on channel %d from %s to %s\n", + cc[x].chan, sigtype_to_str(current_state.sigtype), + sigtype_to_str(cc[x].sigtype)); + } + + if ((cc[x].deflaw != DAHDI_LAW_DEFAULT) && (cc[x].deflaw != current_state.curlaw)) { + needupdate++; + if (verbose > 1) + printf("Changing law on channel %d from %s to %s\n", + cc[x].chan, laws[current_state.curlaw], + laws[cc[x].deflaw]); + } + + if (cc[x].master != master) { + needupdate++; + if (verbose > 1) + printf("Changing master of channel %d from %d to %d\n", + cc[x].chan, master, + cc[x].master); + } + + if (cc[x].idlebits != current_state.idlebits) { + needupdate++; + if (verbose > 1) + printf("Changing idle bits of channel %d from %d to %d\n", + cc[x].chan, current_state.idlebits, + cc[x].idlebits); + } + } + + if (needupdate && ioctl(fd, DAHDI_CHANCONFIG, &cc[x])) { + fprintf(stderr, "DAHDI_CHANCONFIG failed on channel %d: %s (%d)\n", x, strerror(errno), errno); + if (errno == EINVAL) { + /* give helpful suggestions on signaling errors */ + fprintf(stderr, "Selected signaling not " + "supported\n"); + fprintf(stderr, "Possible causes:\n"); + switch(cc[x].sigtype) { + case DAHDI_SIG_FXOKS: + case DAHDI_SIG_FXOLS: + case DAHDI_SIG_FXOGS: + fprintf(stderr, "\tFXO signaling is " + "being used on a FXO interface" + " (use a FXS signaling variant" + ")\n"); + fprintf(stderr, "\tRBS signaling is " + "being used on a E1 CCS span" + "\n"); + break; + case DAHDI_SIG_FXSKS: + case DAHDI_SIG_FXSLS: + case DAHDI_SIG_FXSGS: + fprintf(stderr, "\tFXS signaling is " + "being used on a FXS interface" + " (use a FXO signaling variant" + ")\n"); + fprintf(stderr, "\tRBS signaling is " + "being used on a E1 CCS span" + "\n"); + break; + case DAHDI_SIG_EM: + fprintf(stderr, "\te&m signaling is " + "being used on a E1 line (use" + " e&me1)\n"); + break; + case DAHDI_SIG_EM_E1: + fprintf(stderr, "\te&me1 signaling is " + "being used on a T1 line (use " + "e&m)\n"); + fprintf(stderr, "\tRBS signaling is " + "being used on a E1 CCS span" + "\n"); + break; + case DAHDI_SIG_HARDHDLC: + fprintf(stderr, "\thardhdlc is being " + "used on a TE12x (use dchan)\n" + ); + break; + case DAHDI_SIG_HDLCFCS: + fprintf(stderr, "\tdchan is being used" + " on a BRI span (use hardhdlc)" + "\n"); + break; + default: + break; + } + fprintf(stderr, "\tSignaling is being assigned" + " to channel 16 of an E1 CAS span\n"); + } + close(fd); + exit_code = 1; + goto release_sem; + } + + ae[x].chan = x; + if (verbose) { + printf("Setting echocan for channel %d to %s\n", ae[x].chan, ae[x].echocan[0] ? ae[x].echocan : "none"); + } + + if (ioctl(fd, DAHDI_ATTACH_ECHOCAN, &ae[x])) { + fprintf(stderr, "DAHDI_ATTACH_ECHOCAN failed on channel %d: %s (%d)\n", x, strerror(errno), errno); + close(fd); + exit_code = 1; + goto release_sem; + } + } + if (0 == numzones) { + /* Default to the us zone if one wasn't specified. */ + dahdi_copy_string(zonestoload[numzones++], "us", sizeof(zonestoload[0])); + deftonezone = 0; + } + + for (x=0;x -1) { + if (ioctl(fd, DAHDI_DEFAULTZONE, &deftonezone)) { + fprintf(stderr, "DAHDI_DEFAULTZONE failed: %s (%d)\n", strerror(errno), errno); + close(fd); + exit_code = 1; + goto release_sem; + } + } + for (x=0;x + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include + +#include +#include "dahdi_tools_version.h" + +int main(int argc, char *argv[]) +{ + int fd; + int chan; + if ((argc < 2) || (sscanf(argv[1], "%d", &chan) != 1)) { + fprintf(stderr, "Usage: dahdi_diag \n"); + exit(1); + } + fd = open("/dev/dahdi/ctl", O_RDWR); + if (fd < 0) { + perror("open(/dev/dahdi/ctl"); + exit(1); + } + if (ioctl(fd, DAHDI_CHANDIAG, &chan)) { + perror("ioctl(DAHDI_CHANDIAG)"); + exit(1); + } + exit(0); +} diff --git a/dahdi_maint.c b/dahdi_maint.c new file mode 100644 index 0000000..6777510 --- /dev/null +++ b/dahdi_maint.c @@ -0,0 +1,254 @@ +/* + * Performance and Maintenance utility + * + * Written by Russ Meyerriecks + * + * Copyright (C) 2009-2010 Digium, Inc. + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "dahdi_tools_version.h" + +#define DAHDI_CTL "/dev/dahdi/ctl" + +extern char *optarg; +extern int optind; + +void display_help(char *argv0, int exitcode) +{ + char *c; + c = strrchr(argv0, '/'); + if (!c) + c = argv0; + else + c++; + fprintf(stderr, "%s\n\n", dahdi_tools_version); + fprintf(stderr, "Usage: %s -s \n", c); + fprintf(stderr, "Options:\n"); + fprintf(stderr, " -h, --help display help\n"); + fprintf(stderr, " -s, --span specify the span\n"); + fprintf(stderr, " -l, --loopback \n"\ + "\t\tlocalhost - loop back towards host\n"\ + "\t\tnetworkline - network line loopback\n"\ + "\t\tnetworkpayload - network payload loopback\n"\ + "\t\tloopup - transmit loopup signal\n"\ + "\t\tloopdown - transmit loopdown signal\n"\ + "\t\toff - end loopback mode\n"); + fprintf(stderr, " -i, --insert "\ + "\n\t\tinsert an error of a specific type\n"); + fprintf(stderr, " -r, --reset "\ + "reset the error counters\n\n"); + fprintf(stderr, "Examples: \n"); + fprintf(stderr, "Enable network line loopback\n"); + fprintf(stderr, " dahdi_maint -s 1 --loopback networkline\n"); + fprintf(stderr, "Disable network line loopback\n"); + fprintf(stderr, " dahdi_maint -s 1 --loopback off\n\n"); + + exit(exitcode); +} + +int main(int argc, char *argv[]) +{ + static int ctl = -1; + int res; + + int doloopback = 0; + char *larg = NULL; + int span = 1; + int iflag = 0; + char *iarg = NULL; + int gflag = 0; + int c; + int rflag = 0; + + struct dahdi_maintinfo m; + struct dahdi_spaninfo s; + + static struct option long_options[] = { + {"help", no_argument, 0, 'h'}, + {"loopback", required_argument, 0, 'l'}, + {"span", required_argument, 0, 's'}, + {"insert", required_argument, 0, 'i'}, + {"reset", no_argument, 0, 'r'}, + {0, 0, 0, 0} + }; + int option_index = 0; + + if (argc < 2) { /* no options */ + display_help(argv[0], 1); + } + + while ((c = getopt_long(argc, argv, "hj:l:p:s:i:g:r", + long_options, &option_index)) != -1) { + switch (c) { + case 'h': + display_help(argv[0], 0); + break; + case 'l': /* loopback */ + larg = optarg; + doloopback = 1; + break; + case 's': /* specify a span */ + span = atoi(optarg); + break; + case 'i': /* insert an error */ + iarg = optarg; + iflag = 1; + break; + case 'g': /* generate psuedo random sequence */ + gflag = 1; + break; + case 'r': /* reset the error counters */ + rflag = 1; + break; + } + } + + ctl = open(DAHDI_CTL, O_RDWR); + if (ctl < 0) { + fprintf(stderr, "Unable to open %s\n", DAHDI_CTL); + return -1; + } + + if (!(doloopback || iflag || gflag || rflag)) { + s.spanno = span; + res = ioctl(ctl, DAHDI_SPANSTAT, &s); + if (res || ((__u32)-1 == s.fecount)) + printf("Error counters not supported by the driver"\ + " for this span\n"); + printf("Span %d:\n", span); + printf(">Framing Errors : %d:\n", s.fecount); + printf(">CRC Errors : %d:\n", s.crc4count); + printf(">Code Violations : %d:\n", s.cvcount); + printf(">E-bit Count : %d:\n", s.ebitcount); + printf(">General Errored Seconds : %d:\n", s.errsec); + + return 0; + } + + m.spanno = span; + + if (doloopback) { + if (!strcasecmp(larg, "localhost")) { + printf("Span %d: local host loopback ON\n", span); + m.command = DAHDI_MAINT_LOCALLOOP; + } else if (!strcasecmp(larg, "networkline")) { + printf("Span %d: network line loopback ON\n", span); + m.command = DAHDI_MAINT_NETWORKLINELOOP; + } else if (!strcasecmp(larg, "networkpayload")) { + printf("Span %d: network payload loopback ON\n", span); + m.command = DAHDI_MAINT_NETWORKPAYLOADLOOP; + } else if (!strcasecmp(larg, "loopup")) { + printf("Span %d: transmitting loopup signal\n", span); + m.command = DAHDI_MAINT_LOOPUP; + } else if (!strcasecmp(larg, "loopdown")) { + printf("Span %d: transmitting loopdown signal\n", span); + m.command = DAHDI_MAINT_LOOPDOWN; + } else if (!strcasecmp(larg, "off")) { + printf("Span %d: loopback OFF\n", span); + m.command = DAHDI_MAINT_NONE; + } else { + display_help(argv[0], 1); + } + + res = ioctl(ctl, DAHDI_MAINT, &m); + if (res) { + printf("This type of looping not supported by the"\ + " driver for this span\n"); + return 1; + } + + /* Leave the loopup/loopdown signal on the line for + * five seconds according to AT&T TR 54016 + */ + if ((m.command == DAHDI_MAINT_LOOPUP) || + (m.command == DAHDI_MAINT_LOOPDOWN)) { + sleep(5); + m.command = DAHDI_MAINT_NONE; + ioctl(ctl, DAHDI_MAINT, &m); + } + } + + if (iflag) { + if (!strcasecmp(iarg, "fas")) { + m.command = DAHDI_MAINT_FAS_DEFECT; + printf("Inserting a single FAS defect\n"); + } else if (!strcasecmp(iarg, "multi")) { + m.command = DAHDI_MAINT_MULTI_DEFECT; + printf("Inserting a single multiframe defect\n"); + } else if (!strcasecmp(iarg, "crc")) { + m.command = DAHDI_MAINT_CRC_DEFECT; + printf("Inserting a single CRC defect\n"); + } else if (!strcasecmp(iarg, "cas")) { + m.command = DAHDI_MAINT_CAS_DEFECT; + printf("Inserting a single CAS defect\n"); + } else if (!strcasecmp(iarg, "prbs")) { + m.command = DAHDI_MAINT_PRBS_DEFECT; + printf("Inserting a single PRBS defect\n"); + } else if (!strcasecmp(iarg, "bipolar")) { + m.command = DAHDI_MAINT_BIPOLAR_DEFECT; + printf("Inserting a single bipolar defect\n"); +#ifdef DAHDI_MAINT_ALARM_SIM + } else if (!strcasecmp(iarg, "sim")) { + m.command = DAHDI_MAINT_ALARM_SIM; + printf("Incrementing alarm simulator\n"); +#endif + } else { + display_help(argv[0], 1); + } + res = ioctl(ctl, DAHDI_MAINT, &m); + if (res) + printf("This type of error injection is not supported"\ + " by the driver for this span\n"); + } + + if (gflag) { + printf("Enabled the Pseudo-Random Binary Sequence Generation"\ + " and Monitor\n"); + m.command = DAHDI_MAINT_PRBS; + res = ioctl(ctl, DAHDI_MAINT, &m); + if (res) { + printf("Pseudo-random binary sequence generation is"\ + " not supported by the driver for this span\n"); + } + } + + if (rflag) { + printf("Resetting error counters for span %d\n", span); + m.command = DAHDI_RESET_COUNTERS; + res = ioctl(ctl, DAHDI_MAINT, &m); + if (res) { + printf("Resetting error counters is not supported by"\ + " the driver for this span\n"); + } + } + + return 0; +} diff --git a/dahdi_monitor.c b/dahdi_monitor.c new file mode 100644 index 0000000..79f46dd --- /dev/null +++ b/dahdi_monitor.c @@ -0,0 +1,785 @@ +/* + * Monitor a DAHDI Channel + * + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "dahdi_tools_version.h" +#include "wavformat.h" +#include "autoconfig.h" + +#ifdef HAVE_SYS_SOUNDCARD_H +# include +#else +# ifdef HAVE_LINUX_SOUNDCARD_H +# include +# else +# error "Your installation appears to be missing soundcard.h which is needed to continue." +# endif +#endif + +/* +* defines for file handle numbers +*/ +#define MON_BRX 0 /*!< both channels if multichannel==1 or receive otherwise */ +#define MON_TX 1 /*!< transmit channel */ +#define MON_PRE_BRX 2 /*!< same as MON_BRX but before echo cancellation */ +#define MON_PRE_TX 3 /*!< same as MON_TX but before echo cancellation */ +#define MON_STEREO 4 /*!< stereo mix of rx/tx streams */ +#define MON_PRE_STEREO 5 /*!< stereo mix of rx/tx before echo can. This is exactly what is fed into the echo can */ + +#define BLOCK_SIZE 240 + +#define BUFFERS 4 + +#define FRAG_SIZE 8 + +#define MAX_OFH 6 + +/* Put the ofh (output file handles) outside the main loop in case we ever add a + * signal handler. + */ +static FILE *ofh[MAX_OFH]; +static int run = 1; + +static int stereo; +static int verbose; + +/* handler to catch ctrl-c */ +void cleanup_and_exit(int signal) +{ + fprintf(stderr, "cntrl-c pressed\n"); + run = 0; /* stop reading */ +} + +int filename_is_wav(char *filename) +{ + if (NULL != strstr(filename, ".wav")) + return 1; + return 0; +} + +/* + * Fill the wav header with default info + * num_chans - 0 = mono; 1 = stereo + */ +void wavheader_init(struct wavheader *wavheader, int num_chans) +{ + memset(wavheader, 0, sizeof(struct wavheader)); + + memcpy(&wavheader->riff_chunk_id, "RIFF", 4); + memcpy(&wavheader->riff_type, "WAVE", 4); + + memcpy(&wavheader->fmt_chunk_id, "fmt ", 4); + wavheader->fmt_data_size = 16; + wavheader->fmt_compression_code = 1; + wavheader->fmt_num_channels = num_chans; + wavheader->fmt_sample_rate = 8000; + wavheader->fmt_avg_bytes_per_sec = 16000; + wavheader->fmt_block_align = 2; + wavheader->fmt_significant_bps = 16; + + memcpy(&wavheader->data_chunk_id, "data", 4); +} + +int audio_open(void) +{ + int fd; + int speed = 8000; + int fmt = AFMT_S16_LE; + int fragsize = (BUFFERS << 16) | (FRAG_SIZE); + struct audio_buf_info ispace, ospace; + fd = open("/dev/dsp", O_WRONLY); + if (fd < 0) { + fprintf(stderr, "Unable to open /dev/dsp: %s\n", strerror(errno)); + return -1; + } + /* Step 1: Signed linear */ + if (ioctl(fd, SNDCTL_DSP_SETFMT, &fmt) < 0) { + fprintf(stderr, "ioctl(SETFMT) failed: %s\n", strerror(errno)); + close(fd); + return -1; + } + /* Step 2: Make non-stereo */ + if (ioctl(fd, SNDCTL_DSP_STEREO, &stereo) < 0) { + fprintf(stderr, "ioctl(STEREO) failed: %s\n", strerror(errno)); + close(fd); + return -1; + } + if (stereo != 0) { + fprintf(stderr, "Can't turn stereo off :(\n"); + } + /* Step 3: Make 8000 Hz */ + if (ioctl(fd, SNDCTL_DSP_SPEED, &speed) < 0) { + fprintf(stderr, "ioctl(SPEED) failed: %s\n", strerror(errno)); + close(fd); + return -1; + } + if (speed != 8000) { + fprintf(stderr, "Warning: Requested 8000 Hz, got %d\n", speed); + } + if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fragsize)) { + fprintf(stderr, "Sound card won't let me set fragment size to %u %u-byte buffers (%x)\n" + "so sound may be choppy: %s.\n", BUFFERS, (1 << FRAG_SIZE), fragsize, strerror(errno)); + } + bzero(&ispace, sizeof(ispace)); + bzero(&ospace, sizeof(ospace)); + + if (ioctl(fd, SNDCTL_DSP_GETISPACE, &ispace)) { + /* They don't support block size stuff, so just return but notify the user */ + fprintf(stderr, "Sound card won't let me know the input buffering...\n"); + } + if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &ospace)) { + /* They don't support block size stuff, so just return but notify the user */ + fprintf(stderr, "Sound card won't let me know the output buffering...\n"); + } + fprintf(stderr, "New input space: %d of %d %d byte fragments (%d bytes left)\n", + ispace.fragments, ispace.fragstotal, ispace.fragsize, ispace.bytes); + fprintf(stderr, "New output space: %d of %d %d byte fragments (%d bytes left)\n", + ospace.fragments, ospace.fragstotal, ospace.fragsize, ospace.bytes); + return fd; +} + +int pseudo_open(void) +{ + int fd; + int x = 1; + fd = open("/dev/dahdi/pseudo", O_RDWR); + if (fd < 0) { + fprintf(stderr, "Unable to open pseudo channel: %s\n", strerror(errno)); + return -1; + } + if (ioctl(fd, DAHDI_SETLINEAR, &x)) { + fprintf(stderr, "Unable to set linear mode: %s\n", strerror(errno)); + close(fd); + return -1; + } + x = BLOCK_SIZE; + if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &x)) { + fprintf(stderr, "unable to set sane block size: %s\n", strerror(errno)); + close(fd); + return -1; + } + return fd; +} + +#define barlen 35 +#define baroptimal 3250 +//define barlevel 200 +#define barlevel ((baroptimal/barlen)*2) +#define maxlevel (barlen*barlevel) + +void draw_barheader() +{ + char bar[barlen + 4]; + + memset(bar, '-', sizeof(bar)); + memset(bar, '<', 1); + memset(bar + barlen + 2, '>', 1); + memset(bar + barlen + 3, '\0', 1); + + memcpy(bar + (barlen / 2), "(RX)", 4); + printf("%s", bar); + + memcpy(bar + (barlen / 2), "(TX)", 4); + printf(" %s\n", bar); +} + +void draw_bar(int avg, int max) +{ + char bar[barlen+5]; + + memset(bar, ' ', sizeof(bar)); + + max /= barlevel; + avg /= barlevel; + if (avg > barlen) + avg = barlen; + if (max > barlen) + max = barlen; + + if (avg > 0) + memset(bar, '#', avg); + if (max > 0) + memset(bar + max, '*', 1); + + bar[barlen+1] = '\0'; + printf("%s", bar); + fflush(stdout); +} + +void visualize(short *tx, short *rx, int cnt) +{ + int x; + float txavg = 0; + float rxavg = 0; + static int txmax = 0; + static int rxmax = 0; + static int sametxmax = 0; + static int samerxmax = 0; + static int txbest = 0; + static int rxbest = 0; + float ms; + static struct timeval last; + struct timeval tv; + + gettimeofday(&tv, NULL); + ms = (tv.tv_sec - last.tv_sec) * 1000.0 + (tv.tv_usec - last.tv_usec) / 1000.0; + for (x = 0; x < cnt; x++) { + txavg += abs(tx[x]); + rxavg += abs(rx[x]); + } + txavg = abs(txavg / cnt); + rxavg = abs(rxavg / cnt); + + if (txavg > txbest) + txbest = txavg; + if (rxavg > rxbest) + rxbest = rxavg; + + /* Update no more than 10 times a second */ + if (ms < 100) + return; + + /* Save as max levels, if greater */ + if (txbest > txmax) { + txmax = txbest; + sametxmax = 0; + } + if (rxbest > rxmax) { + rxmax = rxbest; + samerxmax = 0; + } + + memcpy(&last, &tv, sizeof(last)); + + /* Clear screen */ + printf("\r "); + draw_bar(rxbest, rxmax); + printf(" "); + draw_bar(txbest, txmax); + if (verbose) + printf(" Rx: %5d (%5d) Tx: %5d (%5d)", rxbest, rxmax, txbest, txmax); + txbest = 0; + rxbest = 0; + + /* If we have had the same max hits for x times, clear the values */ + sametxmax++; + samerxmax++; + if (sametxmax > 6) { + txmax = 0; + sametxmax = 0; + } + if (samerxmax > 6) { + rxmax = 0; + samerxmax = 0; + } +} + +int main(int argc, char *argv[]) +{ + int afd = -1; + int pfd[4] = {-1, -1, -1, -1}; + short buf_brx[BLOCK_SIZE * 2]; + short buf_tx[BLOCK_SIZE * 4]; + short stereobuf[BLOCK_SIZE * 4]; + int res_brx, res_tx; + int visual = 0; + int multichannel = 0; + int ossoutput = 0; + int preecho = 0; + int savefile = 0; + int stereo_output = 0; + int limit = 0; + int readcount = 0; + int x, chan; + struct dahdi_confinfo zc; + int opt; + extern char *optarg; + struct wavheader wavheaders[MAX_OFH]; /* we have one for each potential filehandle */ + unsigned int bytes_written[MAX_OFH] = {0}; + int file_is_wav[MAX_OFH] = {0}; + int i; + + if ((argc < 2) || (atoi(argv[1]) < 1)) { + fprintf(stderr, "Usage: dahdi_monitor [-v[v]] [-m] [-o] [-l limit] [-f FILE | -s FILE | -r FILE1 -t FILE2] [-F FILE | -S FILE | -R FILE1 -T FILE2]\n"); + fprintf(stderr, "Options:\n"); + fprintf(stderr, " -v: Visual mode. Implies -m.\n"); + fprintf(stderr, " -vv: Visual/Verbose mode. Implies -m.\n"); + fprintf(stderr, " -l LIMIT: Stop after reading LIMIT bytes\n"); + fprintf(stderr, " -m: Separate rx/tx streams.\n"); + fprintf(stderr, " -o: Output audio via OSS. Note: Only 'normal' combined rx/tx streams are output via OSS.\n"); + fprintf(stderr, " -f FILE: Save combined rx/tx stream to mono FILE. Cannot be used with -m.\n"); + fprintf(stderr, " -r FILE: Save rx stream to FILE. Implies -m.\n"); + fprintf(stderr, " -t FILE: Save tx stream to FILE. Implies -m.\n"); + fprintf(stderr, " -s FILE: Save stereo rx/tx stream to FILE. Implies -m.\n"); + fprintf(stderr, " -F FILE: Save combined pre-echocanceled rx/tx stream to FILE. Cannot be used with -m.\n"); + fprintf(stderr, " -R FILE: Save pre-echocanceled rx stream to FILE. Implies -m.\n"); + fprintf(stderr, " -T FILE: Save pre-echocanceled tx stream to FILE. Implies -m.\n"); + fprintf(stderr, " -S FILE: Save pre-echocanceled stereo rx/tx stream to FILE. Implies -m.\n"); + fprintf(stderr, "Examples:\n"); + fprintf(stderr, "Save a stream to a file\n"); + fprintf(stderr, " dahdi_monitor 1 -f stream.raw\n"); + fprintf(stderr, "Visualize an rx/tx stream and save them to separate files.\n"); + fprintf(stderr, " dahdi_monitor 1 -v -r streamrx.raw -t streamtx.raw\n"); + fprintf(stderr, "Play a combined rx/tx stream via OSS and save it to a file\n"); + fprintf(stderr, " dahdi_monitor 1 -o -f stream.raw\n"); + fprintf(stderr, "Save a combined normal rx/tx stream and a combined 'preecho' rx/tx stream to files\n"); + fprintf(stderr, " dahdi_monitor 1 -f stream.raw -F streampreecho.raw\n"); + fprintf(stderr, "Save a normal rx/tx stream and a 'preecho' rx/tx stream to separate files\n"); + fprintf(stderr, " dahdi_monitor 1 -m -r streamrx.raw -t streamtx.raw -R streampreechorx.raw -T streampreechotx.raw\n"); + exit(1); + } + + chan = atoi(argv[1]); + + while ((opt = getopt(argc, argv, "vmol:f:r:t:s:F:R:T:S:")) != -1) { + switch (opt) { + case '?': + exit(EXIT_FAILURE); + case 'v': + if (visual) + verbose = 1; + visual = 1; + multichannel = 1; + break; + case 'm': + multichannel = 1; + break; + case 'o': + ossoutput = 1; + break; + case 'l': + if (sscanf(optarg, "%d", &limit) != 1 || limit < 0) + limit = 0; + fprintf(stderr, "Will stop reading after %d bytes\n", limit); + break; + case 'f': + if (multichannel) { + fprintf(stderr, "'%c' mode cannot be used when multichannel mode is enabled.\n", opt); + exit(EXIT_FAILURE); + } + if (ofh[MON_BRX]) { + fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); + exit(EXIT_FAILURE); + } + if ((ofh[MON_BRX] = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + fprintf(stderr, "Writing combined stream to %s\n", optarg); + file_is_wav[MON_BRX] = filename_is_wav(optarg); + if (file_is_wav[MON_BRX]) { + wavheader_init(&wavheaders[MON_BRX], 1); + if (fwrite(&wavheaders[MON_BRX], 1, sizeof(struct wavheader), ofh[MON_BRX]) != sizeof(struct wavheader)) { + fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + } + savefile = 1; + break; + case 'F': + if (multichannel) { + fprintf(stderr, "'%c' mode cannot be used when multichannel mode is enabled.\n", opt); + exit(EXIT_FAILURE); + } + if (ofh[MON_PRE_BRX]) { + fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); + exit(EXIT_FAILURE); + } + if ((ofh[MON_PRE_BRX] = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + fprintf(stderr, "Writing pre-echo combined stream to %s\n", optarg); + file_is_wav[MON_PRE_BRX] = filename_is_wav(optarg); + if (file_is_wav[MON_PRE_BRX]) { + wavheader_init(&wavheaders[MON_PRE_BRX], 1); + if (fwrite(&wavheaders[MON_PRE_BRX], 1, sizeof(struct wavheader), ofh[MON_PRE_BRX]) != sizeof(struct wavheader)) { + fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + } + preecho = 1; + savefile = 1; + break; + case 'r': + if (!multichannel && ofh[MON_BRX]) { + fprintf(stderr, "'%c' mode cannot be used when combined mode is enabled.\n", opt); + exit(EXIT_FAILURE); + } + if (ofh[MON_BRX]) { + fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); + exit(EXIT_FAILURE); + } + if ((ofh[MON_BRX] = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + fprintf(stderr, "Writing receive stream to %s\n", optarg); + file_is_wav[MON_BRX] = filename_is_wav(optarg); + if (file_is_wav[MON_BRX]) { + wavheader_init(&wavheaders[MON_BRX], 1); + if (fwrite(&wavheaders[MON_BRX], 1, sizeof(struct wavheader), ofh[MON_BRX]) != sizeof(struct wavheader)) { + fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + } + multichannel = 1; + savefile = 1; + break; + case 'R': + if (!multichannel && ofh[MON_PRE_BRX]) { + fprintf(stderr, "'%c' mode cannot be used when combined mode is enabled.\n", opt); + exit(EXIT_FAILURE); + } + if (ofh[MON_PRE_BRX]) { + fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); + exit(EXIT_FAILURE); + } + if ((ofh[MON_PRE_BRX] = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + fprintf(stderr, "Writing pre-echo receive stream to %s\n", optarg); + file_is_wav[MON_PRE_BRX] = filename_is_wav(optarg); + if (file_is_wav[MON_PRE_BRX]) { + wavheader_init(&wavheaders[MON_PRE_BRX], 1); + if (fwrite(&wavheaders[MON_PRE_BRX], 1, sizeof(struct wavheader), ofh[MON_PRE_BRX]) != sizeof(struct wavheader)) { + fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + } + preecho = 1; + multichannel = 1; + savefile = 1; + break; + case 't': + if (!multichannel && ofh[MON_BRX]) { + fprintf(stderr, "'%c' mode cannot be used when combined mode is enabled.\n", opt); + exit(EXIT_FAILURE); + } + if (ofh[MON_TX]) { + fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); + exit(EXIT_FAILURE); + } + if ((ofh[MON_TX] = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + fprintf(stderr, "Writing transmit stream to %s\n", optarg); + file_is_wav[MON_TX] = filename_is_wav(optarg); + if (file_is_wav[MON_TX]) { + wavheader_init(&wavheaders[MON_TX], 1); + if (fwrite(&wavheaders[MON_TX], 1, sizeof(struct wavheader), ofh[MON_TX]) != sizeof(struct wavheader)) { + fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + } + multichannel = 1; + savefile = 1; + break; + case 'T': + if (!multichannel && ofh[MON_PRE_BRX]) { + fprintf(stderr, "'%c' mode cannot be used when combined mode is enabled.\n", opt); + exit(EXIT_FAILURE); + } + if (ofh[MON_PRE_TX]) { + fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); + exit(EXIT_FAILURE); + } + if ((ofh[MON_PRE_TX] = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + fprintf(stderr, "Writing pre-echo transmit stream to %s\n", optarg); + file_is_wav[MON_PRE_TX] = filename_is_wav(optarg); + if (file_is_wav[MON_PRE_TX]) { + wavheader_init(&wavheaders[MON_PRE_TX], 1); + if (fwrite(&wavheaders[MON_PRE_TX], 1, sizeof(struct wavheader), ofh[MON_PRE_TX]) != sizeof(struct wavheader)) { + fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + } + preecho = 1; + multichannel = 1; + savefile = 1; + break; + case 's': + if (!multichannel && ofh[MON_BRX]) { + fprintf(stderr, "'%c' mode cannot be used when combined mode is enabled.\n", opt); + exit(EXIT_FAILURE); + } + if (ofh[MON_STEREO]) { + fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); + exit(EXIT_FAILURE); + } + if ((ofh[MON_STEREO] = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + fprintf(stderr, "Writing stereo stream to %s\n", optarg); + file_is_wav[MON_STEREO] = filename_is_wav(optarg); + if (file_is_wav[MON_STEREO]) { + wavheader_init(&wavheaders[MON_STEREO], 2); + if (fwrite(&wavheaders[MON_STEREO], 1, sizeof(struct wavheader), ofh[MON_STEREO]) != sizeof(struct wavheader)) { + fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + } + multichannel = 1; + savefile = 1; + stereo_output = 1; + break; + case 'S': + if (!multichannel && ofh[MON_PRE_BRX]) { + fprintf(stderr, "'%c' mode cannot be used when combined mode is enabled.\n", opt); + exit(EXIT_FAILURE); + } + if (ofh[MON_PRE_STEREO]) { + fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); + exit(EXIT_FAILURE); + } + if ((ofh[MON_PRE_STEREO] = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + fprintf(stderr, "Writing pre-echo stereo stream to %s\n", optarg); + file_is_wav[MON_PRE_STEREO] = filename_is_wav(optarg); + if (file_is_wav[MON_PRE_STEREO]) { + wavheader_init(&wavheaders[MON_PRE_STEREO], 2); + if (fwrite(&wavheaders[MON_PRE_STEREO], 1, sizeof(struct wavheader), ofh[MON_PRE_STEREO]) != sizeof(struct wavheader)) { + fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + } + preecho = 1; + multichannel = 1; + savefile = 1; + stereo_output = 1; + break; + } + } + + if (ossoutput) { + if (multichannel) { + printf("Multi-channel audio is enabled. OSS output will be disabled.\n"); + ossoutput = 0; + } else { + /* Open audio */ + if ((afd = audio_open()) < 0) { + printf("Cannot open audio ...\n"); + ossoutput = 0; + } + } + } + if (!ossoutput && !multichannel && !savefile) { + fprintf(stderr, "Nothing to do with the stream(s) ...\n"); + exit(1); + } + + /* Open Pseudo device */ + if ((pfd[MON_BRX] = pseudo_open()) < 0) + exit(1); + if (multichannel && ((pfd[MON_TX] = pseudo_open()) < 0)) + exit(1); + if (preecho) { + if ((pfd[MON_PRE_BRX] = pseudo_open()) < 0) + exit(1); + if (multichannel && ((pfd[MON_PRE_TX] = pseudo_open()) < 0)) + exit(1); + } + /* Conference them */ + if (multichannel) { + memset(&zc, 0, sizeof(zc)); + zc.chan = 0; + zc.confno = chan; + /* Two pseudo's, one for tx, one for rx */ + zc.confmode = DAHDI_CONF_MONITOR; + if (ioctl(pfd[MON_BRX], DAHDI_SETCONF, &zc) < 0) { + fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); + exit(1); + } + memset(&zc, 0, sizeof(zc)); + zc.chan = 0; + zc.confno = chan; + zc.confmode = DAHDI_CONF_MONITORTX; + if (ioctl(pfd[MON_TX], DAHDI_SETCONF, &zc) < 0) { + fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); + exit(1); + } + if (preecho) { + memset(&zc, 0, sizeof(zc)); + zc.chan = 0; + zc.confno = chan; + /* Two pseudo's, one for tx, one for rx */ + zc.confmode = DAHDI_CONF_MONITOR_RX_PREECHO; + if (ioctl(pfd[MON_PRE_BRX], DAHDI_SETCONF, &zc) < 0) { + fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); + exit(1); + } + memset(&zc, 0, sizeof(zc)); + zc.chan = 0; + zc.confno = chan; + zc.confmode = DAHDI_CONF_MONITOR_TX_PREECHO; + if (ioctl(pfd[MON_PRE_TX], DAHDI_SETCONF, &zc) < 0) { + fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); + exit(1); + } + } + } else { + memset(&zc, 0, sizeof(zc)); + zc.chan = 0; + zc.confno = chan; + zc.confmode = DAHDI_CONF_MONITORBOTH; + if (ioctl(pfd[MON_BRX], DAHDI_SETCONF, &zc) < 0) { + fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); + exit(1); + } + if (preecho) { + memset(&zc, 0, sizeof(zc)); + zc.chan = 0; + zc.confno = chan; + zc.confmode = DAHDI_CONF_MONITORBOTH_PREECHO; + if (ioctl(pfd[MON_PRE_BRX], DAHDI_SETCONF, &zc) < 0) { + fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); + exit(1); + } + } + } + if (signal(SIGINT, cleanup_and_exit) == SIG_ERR) { + fprintf(stderr, "Error registering signal handler: %s\n", strerror(errno)); + } + if (visual) { + printf("\nVisual Audio Levels.\n"); + printf("--------------------\n"); + printf(" Use chan_dahdi.conf file to adjust the gains if needed.\n\n"); + printf("( # = Audio Level * = Max Audio Hit )\n"); + draw_barheader(); + } + /* Now, copy from pseudo to audio */ + while (run) { + res_brx = read(pfd[MON_BRX], buf_brx, sizeof(buf_brx)); + if (res_brx < 1) + break; + readcount += res_brx; + if (ofh[MON_BRX]) + bytes_written[MON_BRX] += fwrite(buf_brx, 1, res_brx, ofh[MON_BRX]); + + if (multichannel) { + res_tx = read(pfd[MON_TX], buf_tx, res_brx); + if (res_tx < 1) + break; + if (ofh[MON_TX]) + bytes_written[MON_TX] += fwrite(buf_tx, 1, res_tx, ofh[MON_TX]); + + if (stereo_output && ofh[MON_STEREO]) { + for (x = 0; x < res_tx; x++) { + stereobuf[x*2] = buf_brx[x]; + stereobuf[x*2+1] = buf_tx[x]; + } + bytes_written[MON_STEREO] += fwrite(stereobuf, 1, res_tx*2, ofh[MON_STEREO]); + } + + if (visual) { + if (res_brx == res_tx) + visualize((short *)buf_tx, (short *)buf_brx, res_brx/2); + else + printf("Huh? res_tx = %d, res_brx = %d?\n", res_tx, res_brx); + } + } + + if (preecho) { + res_brx = read(pfd[MON_PRE_BRX], buf_brx, sizeof(buf_brx)); + if (res_brx < 1) + break; + if (ofh[MON_PRE_BRX]) + bytes_written[MON_PRE_BRX] += fwrite(buf_brx, 1, res_brx, ofh[MON_PRE_BRX]); + + if (multichannel) { + res_tx = read(pfd[MON_PRE_TX], buf_tx, res_brx); + if (res_tx < 1) + break; + if (ofh[MON_PRE_TX]) + bytes_written[MON_PRE_TX] += fwrite(buf_tx, 1, res_tx, ofh[MON_PRE_TX]); + + if (stereo_output && ofh[MON_PRE_STEREO]) { + for (x = 0; x < res_brx; x++) { + stereobuf[x*2] = buf_brx[x]; + stereobuf[x*2+1] = buf_tx[x]; + } + bytes_written[MON_PRE_STEREO] += fwrite(stereobuf, 1, res_brx * 2, ofh[MON_PRE_STEREO]); + } + } + } + + if (ossoutput && afd) { + if (stereo) { + for (x = 0; x < res_brx; x++) { + buf_tx[x << 1] = buf_tx[(x << 1) + 1] = buf_brx[x]; + } + x = write(afd, buf_tx, res_brx << 1); + } else { + x = write(afd, buf_brx, res_brx); + } + } + + if (limit && readcount >= limit) { + /* bail if we've read too much */ + break; + } + } + /* write filesize info */ + for (i = 0; i < MAX_OFH; i++) { + if (NULL == ofh[i]) + continue; + if (!(file_is_wav[i])) + continue; + + wavheaders[i].riff_chunk_size = (bytes_written[i]) + sizeof(struct wavheader) - 8; /* filesize - 8 */ + wavheaders[i].data_data_size = bytes_written[i]; + + rewind(ofh[i]); + if (fwrite(&wavheaders[i], 1, sizeof(struct wavheader), ofh[i]) != sizeof(struct wavheader)) { + fprintf(stderr, "Failed to write out a full wav header.\n"); + } + fclose(ofh[i]); + } + printf("done cleaning up ... exiting.\n"); + return 0; +} diff --git a/dahdi_pcap.c b/dahdi_pcap.c new file mode 100644 index 0000000..f6fa7fe --- /dev/null +++ b/dahdi_pcap.c @@ -0,0 +1,332 @@ +/* + * Capturing a pcap from the DAHDI interface + * + * Copyright (C) 2011 Torrey Searle + * + * ISDN support added by Horacio Peña + * Command line cleanups by Sverker Abrahamsson + * + * Requirements: + * - pcap development library + * - DAHDI_MIRROR ioctl which isn't enabled by default in dahdi-linux + * To enable this unsupported feature, #define CONFIG_DAHDI_MIRROR + * in dahdi-linux + * - To build this program call the 'make dahdi_pcap' target + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BLOCK_SIZE 512 +#define MAX_CHAN 16 +//char ETH_P_LAPD[2] = {0x00, 0x30}; + +struct mtp2_phdr { + u_int8_t sent; + u_int8_t annex_a_used; + u_int16_t link_number; +}; + + +struct lapd_sll_hdr { + u_int16_t sll_pkttype; /* packet type */ + u_int16_t sll_hatype; + u_int16_t sll_halen; + u_int8_t sll_addr[8]; + u_int8_t sll_protocol[2]; /* protocol, should be ETH_P_LAPD */ +}; + + +struct chan_fds { + int rfd; + int tfd; + int chan_id; + int proto; + char tx_buf[BLOCK_SIZE * 4]; + int tx_len; + char rx_buf[BLOCK_SIZE * 4]; + int rx_len; +}; + +int make_mirror(long type, int chan) +{ + int res = 0; + int fd = 0; + struct dahdi_bufferinfo bi; + fd = open("/dev/dahdi/pseudo", O_RDONLY); + + memset(&bi, 0, sizeof(bi)); + bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; + bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; + bi.numbufs = 32; + bi.bufsize = BLOCK_SIZE; + + ioctl(fd, DAHDI_SET_BUFINFO, &bi); + + res = ioctl(fd, type, &chan); + + if(res) + { + printf("error setting channel err=%d!\n", res); + return -1; + } + + + return fd; +} + +int log_packet(struct chan_fds * fd, char is_read, pcap_dumper_t * dump) +{ + unsigned char buf[BLOCK_SIZE * 4]; + int res = 0; + + struct pcap_pkthdr hdr; + struct mtp2_phdr * mtp2 = (struct mtp2_phdr *)buf; + struct lapd_sll_hdr * lapd = (struct lapd_sll_hdr *)buf; + + unsigned char *dataptr = buf; + int datasize = sizeof(buf); + + if(fd->proto == DLT_LINUX_LAPD) + { + dataptr += sizeof(struct lapd_sll_hdr); + datasize -= sizeof(struct lapd_sll_hdr); + } + else + { + dataptr += sizeof(struct mtp2_phdr); + datasize -= sizeof(struct mtp2_phdr); + } + + memset(buf, 0, sizeof(buf)); + if(is_read) + { + res = read(fd->rfd, dataptr, datasize); + if(fd->rx_len > 0 && res == fd->rx_len && !memcmp(fd->rx_buf, dataptr, res) ) + { + //skipping dup + return 0; + } + + memcpy(fd->rx_buf, dataptr, res); + fd->rx_len = res; + } + else + { + res = read(fd->tfd, dataptr, datasize); + if(fd->tx_len > 0 && res == fd->tx_len && !memcmp(fd->tx_buf, dataptr, res) ) + { + //skipping dup + return 0; + } + + memcpy(fd->tx_buf, dataptr, res); + fd->tx_len = res; + } + + gettimeofday(&hdr.ts, NULL); + + + + + if(res > 0) + { + if(fd->proto == DLT_LINUX_LAPD) + { + hdr.caplen = res+sizeof(struct lapd_sll_hdr)-2; + hdr.len = res+sizeof(struct lapd_sll_hdr)-2; + + lapd->sll_pkttype = 3; + lapd->sll_hatype = 0; + lapd->sll_halen = res; + // lapd->sll_addr = ??? + lapd->sll_protocol[0] = 0x00; + lapd->sll_protocol[1] = 0x30; + + } + else + { + hdr.caplen = res+sizeof(struct mtp2_phdr); + hdr.len = res+sizeof(struct mtp2_phdr); + + if(is_read) + { + mtp2->sent = 0; + mtp2->annex_a_used = 0; + } + else + { + mtp2->sent = 1; + mtp2->annex_a_used = 0; + } + mtp2->link_number = htons(fd->chan_id); + } + pcap_dump((u_char*)dump, &hdr, buf); + pcap_dump_flush(dump); + } + return 1; +} + +void usage() +{ + printf("Usage: dahdi_pcap [OPTIONS]\n"); + printf("Capture packets from DAHDI channels to pcap file\n\n"); + printf("Options:\n"); + printf(" -p, --proto=[mtp2|lapd] The protocol to capture, default mtp2\n"); + printf(" -c, --chan= Comma separated list of channels to capture from, max %d. Mandatory\n", MAX_CHAN); + printf(" -f, --file= The pcap file to capture to. Mandatory\n"); + printf(" -h, --help Display this text\n"); +} + +int main(int argc, char **argv) +{ + struct chan_fds chans[MAX_CHAN]; + char *filename = NULL; + int num_chans = 0; + int max_fd = 0; + int proto = DLT_MTP2_WITH_PHDR; + + int i; + int packetcount; + int c; + + while (1) { + int option_index = 0; + static struct option long_options[] = { + {"proto", required_argument, 0, 'p'}, + {"chan", required_argument, 0, 'c'}, + {"file", required_argument, 0, 'f'}, + {"help", 0, 0, 'h'}, + {0, 0, 0, 0} + }; + + c = getopt_long(argc, argv, "p:c:f:?", + long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 'p': + // Protocol + if(strcasecmp("LAPD", optarg)==0) + { + proto = DLT_LINUX_LAPD; + } + else if(argc > 0 && strcasecmp("MTP2", argv[1])==0) + { + proto = DLT_MTP2_WITH_PHDR; + } + break; + case 'c': + // TODO Should it be possible to override protocol per channel? + // Channels, comma separated list + while(optarg != NULL && num_chans < MAX_CHAN) + { + int chan = atoi(strsep(&optarg, ",")); + + + chans[num_chans].tfd = make_mirror(DAHDI_TXMIRROR, chan); + chans[num_chans].rfd = make_mirror(DAHDI_RXMIRROR, chan); + chans[num_chans].chan_id = chan; + chans[num_chans].proto = proto; + + if(chans[num_chans].tfd > max_fd) + { + max_fd = chans[num_chans].tfd; + } + if(chans[num_chans].rfd > max_fd) + { + max_fd = chans[num_chans].rfd; + } + + num_chans++; + } + max_fd++; + break; + case 'f': + // File to capture to + filename=optarg; + break; + case 'h': + default: + // Usage + usage(); + exit(0); + } + } + if((num_chans == 0) || (filename == NULL)) { + usage(); + exit(0); + } + else + { + printf("Capturing protocol %s on channels ", (proto == DLT_MTP2_WITH_PHDR ? "mtp2":"lapd")); + for(i = 0; i < num_chans; i++) + { + printf("%d", chans[i].chan_id); + if(i + * and Kevin P. Fleming + * Copyright (C) 2007 Digium, Inc. + * + * Based on zttool written by Mark Spencer + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "dahdi_tools_version.h" + +static inline int is_digital_span(struct dahdi_spaninfo *s) +{ + return (s->linecompat > 0); +} + +static int get_basechan(unsigned int spanno) +{ + int res; + int basechan; + char filename[256]; + FILE *fp; + + snprintf(filename, sizeof(filename), + "/sys/bus/dahdi_spans/devices/span-%u/basechan", spanno); + fp = fopen(filename, "r"); + if (NULL == fp) { + return -1; + } + res = fscanf(fp, "%d", &basechan); + fclose(fp); + if (EOF == res) { + return -1; + } + return basechan; +} + + +int main(int argc, char *argv[]) +{ + int ctl; + int x, y, z; + struct dahdi_params params; + unsigned int basechan = 1; + int direct_basechan; + struct dahdi_spaninfo s; + char buf[100]; + char alarms[50]; + int filter_count = 0; + int span_filter[DAHDI_MAX_SPANS]; + + if ((ctl = open("/dev/dahdi/ctl", O_RDWR)) < 0) { + fprintf(stderr, "Unable to open /dev/dahdi/ctl: %s\n", strerror(errno)); + exit(1); + } + + for (x = 1; x < argc && filter_count < DAHDI_MAX_SPANS; x++) { + int s = atoi(argv[x]); + if (s > 0) { + span_filter[filter_count++] = s; + } + } + + for (x = 1; x < DAHDI_MAX_SPANS; x++) { + + memset(&s, 0, sizeof(s)); + s.spanno = x; + if (ioctl(ctl, DAHDI_SPANSTAT, &s)) + continue; + + if (filter_count > 0) { + int match = 0; + for (z = 0; z < filter_count; z++) { + if (x == span_filter[z]) { + match = 1; + break; + } + } + if (!match) { + basechan += s.totalchans; + continue; + } + } + + /* DAHDI-Linux 2.5.x exposes the base channel in sysfs. Let's + * try to look for it there in case there are holes in the span + * numbering. */ + direct_basechan = get_basechan(x); + if (-1 != direct_basechan) { + basechan = direct_basechan; + } + + alarms[0] = '\0'; + if (s.alarms) { + if (s.alarms & DAHDI_ALARM_BLUE) + strcat(alarms,"BLU/"); + if (s.alarms & DAHDI_ALARM_YELLOW) + strcat(alarms, "YEL/"); + if (s.alarms & DAHDI_ALARM_RED) { + strcat(alarms, "RED/"); + +/* Extended alarm feature test. Allows compilation with + * versions of dahdi-linux prior to 2.4 + */ +#ifdef DAHDI_ALARM_LFA + if (s.alarms & DAHDI_ALARM_LFA) + strcat(alarms, "LFA/"); +#endif /* ifdef DAHDI_ALARM_LFA */ + } + if (s.alarms & DAHDI_ALARM_LOOPBACK) + strcat(alarms,"LB/"); + if (s.alarms & DAHDI_ALARM_RECOVER) + strcat(alarms,"REC/"); + if (s.alarms & DAHDI_ALARM_NOTOPEN) + strcat(alarms, "NOP/"); + if (!strlen(alarms)) + strcat(alarms, "UUU/"); + if (strlen(alarms)) { + /* Strip trailing / */ + alarms[strlen(alarms)-1]='\0'; + } + } else { + if (s.numchans) { +#ifdef DAHDI_ALARM_LFA + /* If we continuously receive framing errors + * but our span is still in service, and we + * are configured for E1 & crc4. We've lost + * crc4-multiframe alignment + */ + if ((s.linecompat & DAHDI_CONFIG_CRC4) && + (s.fecount > 0)) { + struct dahdi_spaninfo t; + memset(&t, 0, sizeof(t)); + t.spanno = x; + sleep(1); + if (ioctl(ctl, DAHDI_SPANSTAT, &t)) + continue; + + /* Test fecount at two separate time + * intervals, if they differ, throw LMFA + */ + if ((t.fecount > s.fecount) && + !t.alarms) { + strcat(alarms, "LMFA/"); + } + } +#endif /* ifdef DAHDI_ALARM_LFA */ + strcat(alarms, "OK"); + } else { + strcpy(alarms, "UNCONFIGURED"); + } + } + + fprintf(stdout, "[%d]\n", x); + fprintf(stdout, "active=yes\n"); + fprintf(stdout, "alarms=%s\n", alarms); + fprintf(stdout, "description=%s\n", s.desc); + fprintf(stdout, "name=%s\n", s.name); + fprintf(stdout, "manufacturer=%s\n", s.manufacturer); + fprintf(stdout, "devicetype=%s\n", s.devicetype); + fprintf(stdout, "location=%s\n", s.location); + fprintf(stdout, "basechan=%d\n", basechan); + fprintf(stdout, "totchans=%d\n", s.totalchans); + fprintf(stdout, "irq=%d\n", s.irq); + y = basechan; + memset(¶ms, 0, sizeof(params)); + params.channo = y; + if (ioctl(ctl, DAHDI_GET_PARAMS, ¶ms)) { + basechan += s.totalchans; + continue; + } + + if (is_digital_span(&s)) { + /* this is a digital span */ + fprintf(stdout, "type=digital-%s\n", s.spantype); + fprintf(stdout, "syncsrc=%d\n", s.syncsrc); + fprintf(stdout, "lbo=%s\n", s.lboname); + fprintf(stdout, "coding_opts="); + buf[0] = '\0'; + if (s.linecompat & DAHDI_CONFIG_B8ZS) strcat(buf, "B8ZS,"); + if (s.linecompat & DAHDI_CONFIG_AMI) strcat(buf, "AMI,"); + if (s.linecompat & DAHDI_CONFIG_HDB3) strcat(buf, "HDB3,"); + buf[strlen(buf) - 1] = '\0'; + fprintf(stdout, "%s\n", buf); + fprintf(stdout, "framing_opts="); + buf[0] = '\0'; + if (s.linecompat & DAHDI_CONFIG_ESF) strcat(buf, "ESF,"); + if (s.linecompat & DAHDI_CONFIG_D4) strcat(buf, "D4,"); + if (s.linecompat & DAHDI_CONFIG_CCS) strcat(buf, "CCS,"); + if (s.linecompat & DAHDI_CONFIG_CRC4) strcat(buf, "CRC4,"); + buf[strlen(buf) - 1] = '\0'; + fprintf(stdout, "%s\n", buf); + fprintf(stdout, "coding="); + if (s.lineconfig & DAHDI_CONFIG_B8ZS) fprintf(stdout, "B8ZS"); + else if (s.lineconfig & DAHDI_CONFIG_AMI) fprintf(stdout, "AMI"); + else if (s.lineconfig & DAHDI_CONFIG_HDB3) fprintf(stdout, "HDB3"); + fprintf(stdout, "\n"); + fprintf(stdout, "framing="); + if (s.lineconfig & DAHDI_CONFIG_ESF) fprintf(stdout, "ESF"); + else if (s.lineconfig & DAHDI_CONFIG_D4) fprintf(stdout, "D4"); + else if (s.lineconfig & DAHDI_CONFIG_CCS) fprintf(stdout, "CCS"); + else fprintf(stdout, "CAS"); + if (s.lineconfig & DAHDI_CONFIG_CRC4) fprintf(stdout, "/CRC4"); + fprintf(stdout, "\n"); + } else { + /* this is an analog span */ + fprintf(stdout, "type=analog\n"); + for (y = basechan; y < (basechan + s.totalchans); y++) { + memset(¶ms, 0, sizeof(params)); + params.channo = y; + if (ioctl(ctl, DAHDI_GET_PARAMS, ¶ms)) { + fprintf(stdout, "port=%d,unknown\n", y); + continue; + }; + fprintf(stdout, "port=%d,", y); + switch (params.sigcap & (__DAHDI_SIG_FXO | __DAHDI_SIG_FXS)) { + case __DAHDI_SIG_FXO: + fprintf(stdout, "FXS"); + break; + case __DAHDI_SIG_FXS: + fprintf(stdout, "FXO"); + break; + default: + fprintf(stdout, "none"); + } + if (params.sigcap & DAHDI_SIG_BROKEN) + fprintf(stdout, " FAILED"); + fprintf(stdout, "\n"); + } + } + + basechan += s.totalchans; + } + + exit(0); +} diff --git a/dahdi_span_assignments b/dahdi_span_assignments new file mode 100755 index 0000000..bcafe89 --- /dev/null +++ b/dahdi_span_assignments @@ -0,0 +1,333 @@ +#! /bin/sh +# +# /usr/sbin/dahdi_span_assignments: +# +# this script can be used both from udev and +# from the command line to assign/unassign and list +# current span assignments. +# +# It uses a configuration file: $DAHDICONFDIR/assigned-spans.conf +# (default DAHDICONFDIR=/etc/dahdi) +# +# The first argument is an action: +# "auto" - trigger driver auto_assign attribute for given devices +# (no configuration file is used) +# "add" - assign (spans which are not already assigned), according +# to /etc/dahdi/assigned-spans.conf configuration file +# "remove" - unassign spans which are not already unassigned +# "list" - human-readable list of all spans (with/without assignments) +# "dumpconfig" - dump current assignments in a /etc/dahdi/assigned-spans.conf +# compatible format +# +# Without further arguments, it operates on all existing spans +# With one or more sysfs dahdi_devices it is limited to those. +# +# We may use alternative "keys" for device matching: +# * Available keys: +# - "hwid" - Hardware id attribute from sysfs +# - "@location" - Location attribute from sysfs (embeded inside '<>') +# - "/devpath" - The sysfs absolute devpath +# +# * During "dumpconfig", for each device we take the first available key: +# - The preference is: "hwid" or else "@location" or else "/devpath" +# - This can be overriden via the SPAN_ASSIGNMENTS_KEY environment variable +# or the '{-k|--key} key' command line option. +# +# * During "add": +# - Any key match is valid (hwid/location/devpath) +# - Shell globs (wildcards: '*', '?', '[...]') may be optionally used. +# +# Command line options: +# - The '-h|--help' show a usage message. +# - The '-n|--dry-run' affects the "add" and "remove" operations. +# - The '-v|--verbose' currently shows device matches during "add" operation. +# - The '-k |--key ' overrides the SPAN_ASSIGNMENTS_KEY environment +# variable. +# +# Examples: +# dahdi_span_assignments list +# dahdi_span_assignments add # all unassigned devices +# dahdi_span_assignments add /sys/bus/dahdi_devices/devices/astribanks:xbus-00 +# dahdi_span_assignments remove # all assigned devices +# dahdi_span_assignments -k location dumpconfig +# + +devbase='/sys/bus/dahdi_devices/devices' +DAHDICONFDIR="${DAHDICONFDIR:-/etc/dahdi}" +DAHDISASSIGNEDSPANSCONF="${DAHDIASSIGNEDSPANSCONF:-"${DAHDICONFDIR}/assigned-spans.conf"}" +SPAN_ASSIGNMENTS_KEY=${SPAN_ASSIGNMENTS_KEY:-hwid} +dry_run= +verbose= + +usage() { + echo >&2 "Usage: $0 [options] action [devpath ...]" + echo >&2 " action:" + echo >&2 " auto - trigger driver auto_assign attribute for given devices" + echo >&2 " add - assign spans, according to /etc/dahdi/assigned-spans.conf" + echo >&2 " remove - unassign spans" + echo >&2 " list - human-readable list of all spans" + echo >&2 " dumpconfig - dump current state as new configuration" + echo >&2 "" + echo >&2 " options:" + echo >&2 " -h|--help - Show this help" + echo >&2 " -n|--dry-run - For 'add/remove' actions" + echo >&2 " -v|--versbose - Show matches during 'add' action" + echo >&2 " -k|--key - Override prefered key during dumpconfig action" + exit 1 +} + +# Parse command line options +TEMP=`getopt -o hnvk: --long help,dry-run,verbose,key: -n "$0" -- "$@"` +if [ $? != 0 ]; then + echo >&2 "Bad options" + usage +fi + +# Note the quotes around `$TEMP': they are essential! +eval set -- "$TEMP" + +while true ; do + case "$1" in + -h|--help) + usage + ;; + -n|--dry-run) + dry_run='true' + shift + ;; + -v|--verbose) + verbose='true' + shift + ;; + -k|--key) + SPAN_ASSIGNMENTS_KEY="$2" + shift + shift + ;; + --) + shift + break + ;; + *) + echo "Internal error!" + exit 1 + ;; + esac +done + +if [ "$#" -eq 0 ]; then + echo >&2 "Missing action argument" + usage +fi +action="$1" +shift + +# Validate SPAN_ASSIGNMENTS_KEY +case "$SPAN_ASSIGNMENTS_KEY" in +hwid|location|devpath) + ;; +*) + echo >&2 "Bad SPAN_ASSIGNMENTS_KEY='$SPAN_ASSIGNMENTS_KEY' (should be: hwid|location|devpath)" + usage + ;; +esac + +if [ ! -d "$devbase" ]; then + echo >&2 "$0: Missing '$devbase' (DAHDI driver unloaded?)" + exit 1 +fi + +# Use given devices or otherwise, all existing devices +if [ "$#" -gt 0 ]; then + DEVICES="$@" +else + DEVICES=`ls -d $devbase/* 2>/dev/null` +fi + +# Beware of special characters in attributes +attr_clean() { + cat "$1" 2>/dev/null | tr -d '\n' | tr '!' '/' | tr -c 'a-zA-Z0-9/:.-' '_' +} + +show_devices() { + + for device in $DEVICES + do + devpath=`cd "$device" && pwd -P` + location='@'`attr_clean "$device/location"` + hardware_id=`attr_clean "$device/hardware_id"` + for local_spanno in `cut -d: -f1 "$device/spantype"` + do + span=`grep 2>/dev/null -Hw "$local_spanno" "$device/span-"*"/local_spanno" | \ + sed -e 's,/local_spanno:.*,,' -e 's,.*/,,'` + if [ "$span" != '' ]; then + spanno=`echo $span | sed 's/^.*-//'` + name=`cat 2>/dev/null "$device/$span/name"` + basechan=`cat 2>/dev/null "$device/$span/basechan"` + else + spanno='-' + basechan='-' + fi + printf "%-8s %-14s %s %s\n" "$local_spanno:$spanno:$basechan" "[$hardware_id]" "$location" "$devpath" + done | sort -n + done +} + +dump_config() { + echo '#' + echo "# Autogenerated by $0 on `date`" + echo "# Map devices + local spans to span + base channel number" + echo '' + for device in $DEVICES + do + devpath=`cd "$device" && pwd -P` + location=`attr_clean "$device/location"` + hardware_id=`attr_clean "$device/hardware_id"` + if [ "$SPAN_ASSIGNMENTS_KEY" = 'hwid' -a "$hardware_id" != '' ]; then + id="$hardware_id" + elif [ "$SPAN_ASSIGNMENTS_KEY" = 'location' -a "$location" != '' ]; then + id="@$location" + else + id="$devpath" + fi + echo "# Device: [$hardware_id] @$location $devpath" + for local_spanno in `cut -d: -f1 "$device/spantype"` + do + span=`grep 2>/dev/null -Hw "$local_spanno" "$device/span-"*"/local_spanno" | \ + sed -e 's,/local_spanno:.*,,' -e 's,.*/,,'` + if [ "$span" != '' ]; then + spanno=`echo $span | sed 's/^.*-//'` + name=`cat 2>/dev/null "$device/$span/name"` + basechan=`cat 2>/dev/null "$device/$span/basechan"` + printf "%-30s %s\n" "$id" "$local_spanno:$spanno:$basechan" + else + echo "# Skipped unassigned local span $local_spanno" + fi + done | sort + echo '' + done +} + +unassign_all_spans() { + for device in $DEVICES + do + find "$device" -follow -maxdepth 1 -name 'span-*' -type d | \ + sort | while read spandir; do + local_spanno=`cat "$spandir/local_spanno"` + if [ "$dry_run" = true ]; then + echo "(dry-run) unassign $device $local_spanno" + continue + fi + echo "unassign $device $local_spanno" + if ! echo "$local_spanno" > "$device/unassign_span"; then + echo >&2 "$0: failed unassigning '$local_spanno' in '$device'" + fi + done + done +} + +# Allow comments and empty lines in config file +filter_conf() { + sed -e 's/#.*//' -e '/^[ \t]*$/d' "$DAHDISASSIGNEDSPANSCONF" +} + +assign_device_spans() { + device="$1" + for s in $spanspecs + do + local_spanno=`echo "$s" | cut -d: -f1` + spanno=`echo "$s" | cut -d: -f2` + span="$device/span-$spanno" + if [ "$dry_run" = true ]; then + echo "(dry-run) assign $device: $s" + continue + fi + if [ -d "$span" ]; then + span_local_spanno=`cat "$span/local_spanno"` + if [ "$span_local_spanno" != "$local_spanno" ]; then + echo "WARNING: $span_local_spanno != $local_spanno" + fi + echo "$device [$local_spanno] already assigned to span $spanno. Skipping..." + continue + fi + echo "assign $device: $s" + if ! echo "$s" > "$device/assign_span"; then + echo >&2 "$0: failed assigning '$s' to '$device'" + fi + done +} + +match_device() { + device="$1" + devpath=`cd "$device" && pwd -P` + location='@'`attr_clean "$device/location"` + hardware_id=`attr_clean "$device/hardware_id"` + filter_conf | while read id spanspecs + do + # We use case to enable shell-style globbing in configuration + case "$hardware_id" in + $id) + [ "$verbose" = true ] && echo "match by hwid ($id ~ $hardware_id): $spanspecs" + assign_device_spans "$device" + ;; + esac + # We use case to enable shell-style globbing in configuration + case "$location" in + $id) + [ "$verbose" = true ] && echo "match by location ($id ~ $location): $spanspecs" + assign_device_spans "$device" + ;; + esac + # We use case to enable shell-style globbing in configuration + case "$devpath" in + $id) + [ "$verbose" = true ] && echo "match by devpath ($id ~ $devpath): $spanspecs" + assign_device_spans "$device" + ;; + esac + done +} + +assign_devices() { + if [ ! -f "$DAHDISASSIGNEDSPANSCONF" ]; then + echo >&2 "$0: Missing '$DAHDISASSIGNEDSPANSCONF'" + exit 1 + fi + echo "using '$DAHDISASSIGNEDSPANSCONF'" + for device in $DEVICES + do + match_device "$device" + done +} + +auto_assign_devices() { + for device in $DEVICES + do + echo "auto-assign $device" + if [ "$dry_run" != true ]; then + echo 1 > "$device/auto_assign" + fi + done +} + +case "$action" in +auto) + auto_assign_devices + ;; +add) + assign_devices + ;; +remove) + unassign_all_spans + ;; +list) + show_devices + ;; +dumpconfig) + dump_config + ;; +*) + echo >&2 "Bad action='$action'" + usage + ;; +esac diff --git a/dahdi_span_types b/dahdi_span_types new file mode 100755 index 0000000..4154772 --- /dev/null +++ b/dahdi_span_types @@ -0,0 +1,366 @@ +#! /bin/sh +# +# /usr/sbin/dahdi_span_types +# +# This script can be used both from udev and +# from the command line to manage PRI spans +# type (E1/T1/J1). +# +# Span types can be set only *BEFORE* span are assigned. +# +# It uses a configuration file: $DAHDICONFDIR/span-types.conf +# (default DAHDICONFDIR=/etc/dahdi) +# (the format is documented inside that file) +# +# The first argument is an action: +# "set" - actually write the setting to the driver +# "list" - human-readable list of E1/T1/J1 types +# "dumpconfig" - dump current assignments in a /etc/dahdi/span-types.conf +# compatible format +# +# Without further arguments, it operates on all existing spans +# With one or more sysfs dahdi_devices it is limited to those. +# +# We may use alternative "keys" for device matching: +# * Available keys: +# - "hwid" - Hardware id attribute from sysfs +# - "@location" - Location attribute from sysfs (embeded inside '<>') +# - "/devpath" - The sysfs absolute devpath +# +# * Wildcard are allowed in the configuration file: +# - In the device specifiers (keys) +# - In the span numbers +# - Example for "match-all": * *:T1 +# +# * During "set": +# - If there are multiple matches, for a span, all are applied +# - They are always applied in their order in the configuration file +# - This means the last match wins +# - Example: +# * *:T1 # All span on all devices are T1 +# usb:X1234567 [34]:E1 # Except spans 3,4 on specific device +# +# * During "dumpconfig", for each device we take the first available key: +# - The preference is: "hwid" or else "@location" or else "/devpath" +# - This can be overriden via the SPAN_ASSIGNMENTS_KEY environment variable +# or the '{-k|--key} key' command line option. +# +# Command line options: +# - The '-h|--help' show a usage message. +# - The '-v|--verbose' show debugging messages (on stderr) +# - The '-n|--dry-run' During "set", only show what would be done +# - The '-k |--key ' overrides the SPAN_ASSIGNMENTS_KEY environment +# variable. +# +# Examples: +# dahdi_span_types list +# dahdi_span_types set # all devices +# dahdi_span_types set /sys/bus/dahdi_devices/devices/astribanks:xbus-00 +# dahdi_span_types -k location dumpconfig +# + + +devbase='/sys/bus/dahdi_devices/devices' +DAHDICONFDIR="${DAHDICONFDIR:-/etc/dahdi}" +DAHDISPANTYPESCONF="${DAHDISPANTYPESCONF:-"${DAHDICONFDIR}/span-types.conf"}" +SPAN_ASSIGNMENTS_KEY=${SPAN_ASSIGNMENTS_KEY:-hwid} + +usage() { + echo >&2 "Usage: $0 [options] action [devpath ...]" + echo >&2 " action:" + echo >&2 " set - set spans to E1/T1 according to /etc/dahdi/span-types.conf" + echo >&2 " list - human-readable list of all spans" + echo >&2 " dumpconfig - dump current state in /etc/dahdi/span-types.conf format" + echo >&2 "" + echo >&2 " options:" + echo >&2 " -h|--help - Show this help" + echo >&2 " -v|--verbose' - Show debugging messages (on stderr)" + echo >&2 " -n|--dry-run' - During 'set', only show what would be done" + echo >&2 " -k|--key - Override prefered key during dumpconfig action" + echo >&2 " --line-mode - Set default line mode to (E1/T1/J1)" + exit 1 +} + +# Parse command line options +TEMP=`getopt -o hnvk: --long help,dry-run,verbose,key:,line-mode: -n "$0" -- "$@"` +if [ $? != 0 ]; then + echo >&2 "Bad options" + usage +fi + +# Note the quotes around `$TEMP': they are essential! +eval set -- "$TEMP" + +while true ; do + case "$1" in + -h|--help) + usage + ;; + -n|--dry-run) + shift + dry_run=true + ;; + -v|--verbose) + shift + verbose=true + ;; + -k|--key) + SPAN_ASSIGNMENTS_KEY="$2" + shift + shift + ;; + --line-mode) + DEFAULT_LINE_MODE="$2" + shift + shift + ;; + --) + shift + break + ;; + *) + echo "Internal error!" + exit 1 + ;; + esac +done + +if [ "$#" -eq 0 ]; then + echo >&2 "Missing action argument" + usage +fi +action="$1" +shift + +# Validate SPAN_ASSIGNMENTS_KEY +case "$SPAN_ASSIGNMENTS_KEY" in +hwid|location|devpath) + ;; +*) + echo >&2 "Bad --key='$SPAN_ASSIGNMENTS_KEY' (should be: hwid|location|devpath)" + usage + ;; +esac + +# Validate DEFAULT_LINE_MODE +case "$DEFAULT_LINE_MODE" in +E1|T1|J1|'') + ;; +*) + echo >&2 "Bad --line-mode='$DEFAULT_LINE_MODE' (should be: E1|T1|J1)" + usage + ;; +esac + +if [ ! -d "$devbase" ]; then + echo >&2 "$0: Missing '$devbase' (DAHDI driver unloaded?)" + exit 1 +fi + +# Use given devices or otherwise, all existing devices +if [ "$#" -gt 0 ]; then + DEVICES="$@" +else + DEVICES=`ls -d $devbase/* 2>/dev/null` +fi + +# Beware of special characters in attributes +attr_clean() { + cat "$1" 2>/dev/null | tr -d '\n' | tr '!' '/' | tr -c 'a-zA-Z0-9/:.-' '_' +} + +show_spantypes() { + echo "# PRI span types (E1/T1/J1)" + for device in $DEVICES + do + devpath=`cd "$device" && pwd -P` + location='@'`attr_clean "$device/location"` + hardware_id=`attr_clean "$device/hardware_id"` + cat "$device/spantype" | while read st; do + case "$st" in + *:[ETJ]1) + printf "%-10s %-20s %-30s %s\n" \ + "$st" "[$hardware_id]" "$location" \ + "$devpath" + ;; + esac + done + done +} + +list_pri_spantypes() { + find $DEVICES -follow -maxdepth 1 -name spantype | \ + xargs cat | \ + sed -n '/:[ETJ]1$/s/^.*://p' | \ + sort -u | \ + tr '\n' ' ' | \ + sed -e 's/^ *//' -e 's/ *$//' +} + +dump_config() { + pri_spantypes=`list_pri_spantypes` + num_spantypes=`echo "$pri_spantypes" | wc -w` + gen_default='' + echo '#' + echo "# Autogenerated by $0 on `date`" + echo "# Map PRI DAHDI devices to span types for E1/T1/J1" + echo "#" + + echo "# Summary:" + if [ "$DEFAULT_LINE_MODE" != '' ]; then + gen_default="$DEFAULT_LINE_MODE" + echo "# * Generating wildcard match of $gen_default." + echo "# - Was run with '--line-mode=$DEFAULT_LINE_MODE'" + elif [ "$num_spantypes" -eq 1 ]; then + gen_default="$pri_spantypes" + echo "# * Generating wildcard match of $gen_default." + echo "# - Spans were $pri_spantypes" + else + echo "# * Not generating wildcard match." + echo "# - Was run without '--line-mode' option and span were of mixed types [$pri_spantypes]" + fi + echo "#" + if [ "$num_spantypes" -eq 1 ]; then + echo "# * Generating a list of commented out configurations for spans." + echo "# - Spans were $pri_spantypes" + echo "# - Uncomment for specific overrides" + else + echo "# * Generating a list of specific span configurations." + echo "# - Spans were of mixed types: $pri_spantypes" + fi + echo "#" + echo '' + + fmt="%-65s %s" + printf "$fmt\n" '# @location/hardware_id' 'span_type' + + if [ "$gen_default" != '' ]; then + printf "$fmt\t\t# Wildcard line-mode" "*" "*:$gen_default" + echo "" + fi + echo "" + for device in $DEVICES + do + devpath=`cd "$device" && pwd -P` + location=`attr_clean "$device/location"` + hardware_id=`attr_clean "$device/hardware_id"` + if [ "$SPAN_ASSIGNMENTS_KEY" = 'hwid' -a "$hardware_id" != '' ]; then + id="$hardware_id" + elif [ "$SPAN_ASSIGNMENTS_KEY" = 'location' -a "$location" != '' ]; then + id="@$location" + else + id="$devpath" + fi + echo "# Device: [$hardware_id] @$location $devpath" + cat "$device/spantype" | while read st; do + case "$st" in + *:[ETJ]1) + if [ "$num_spantypes" -eq 1 ]; then + printf "#$fmt\n" "$id" "$st" + else + printf "$fmt\n" "$id" "$st" + fi + ;; + *) + #echo "# Skipped local span `echo $st | sed 's/:/ -- /'`" + ;; + esac + done | sort -n + echo '' + done +} + +# Allow comments and empty lines in config file +filter_conf() { + sed -e 's/#.*//' -e '/^[ \t]*$/d' "$DAHDISPANTYPESCONF" +} + +handle_span() { + device="$1" + spantype="$2" + attr_file="$device/spantype" + devpath=`cd "$device" && pwd -P` + devname=`echo "$device" | sed "s,$devbase/,,"` + location='@'`attr_clean "$device/location"` + hardware_id=`attr_clean "$device/hardware_id"` + spanno=`echo "$spantype" | cut -d: -f1` + #echo >&2 "DEBUG: $device $spanno ($spantype)" + filter_conf | while read id span_spec; do + sn=`echo "$span_spec" | cut -d: -f1` + val=`echo "$span_spec" | cut -d: -f2` + case "$spanno" in + $sn) + ;; + *) + #echo >&2 "no-match($device $spanno): $sn" + continue + ;; + esac + found=no + # GLOBBING + case "$location" in + $id) + #echo >&2 "match($id): $span_spec" + found=yes + ;; + esac + case "$hardware_id" in + $id) + #echo >&2 "match([$id]): $span_spec" + found=yes + ;; + esac + case "$devpath" in + $id) + #echo >&2 "match([$id]): $span_spec" + found=yes + ;; + esac + if [ "$found" = 'yes' ]; then + if [ "$dry_run" = 'true' -o "$verbose" = 'true' ]; then + echo >&2 "Set $devname span $spanno = $val" + fi + if [ "$dry_run" != 'true' ]; then + echo "$spanno:$val" > "$attr_file" + fi + fi + done +} + +set_all_devices() { + if [ ! -f "$DAHDISPANTYPESCONF" ]; then + echo >&2 "$0: Missing configuration '$DAHDISPANTYPESCONF'" + exit 1 + fi + for device in $DEVICES + do + devname=`echo "$device" | sed "s,$devbase/,,"` + cat "$device/spantype" | while read spantype; do + case "$spantype" in + *:[ETJ]1) + handle_span "$device" "$spantype" + ;; + *) + if [ "$dry_run" = 'true' -o "$verbose" = 'true' ]; then + echo >&2 "Skipping non-E1/T1/J1 span ($devname -- $spantype)" + fi + ;; + esac + done + done +} + +case "$action" in +list) + show_spantypes + ;; +dumpconfig) + dump_config + ;; +set) + set_all_devices + ;; +*) + usage + ;; +esac diff --git a/dahdi_speed.c b/dahdi_speed.c new file mode 100644 index 0000000..75bfa86 --- /dev/null +++ b/dahdi_speed.c @@ -0,0 +1,65 @@ +/* + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * + * Generic speed test -- Run an infinite loop and + * see how high we can count (in 5 seconds). You + * can use this to measure how much CPU DAHDI REALLY + * is taking. + * + * MUST BE COMPILED WITHOUT OPTIMIZATION + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include + +#include "dahdi_tools_version.h" + +static long count=0; + +static void alm(int sig) +{ + printf("Count: %ld\n", count); + exit(0); +} + + +int main(int argc, char *argv[]) +{ + int a=0,b=0,c; + signal(SIGALRM, alm); + alarm(5); + for (;;) { + for (c=0;c<1000;c++) + a = a * b; + count++; + } +} diff --git a/dahdi_test.c b/dahdi_test.c new file mode 100644 index 0000000..d07a1f6 --- /dev/null +++ b/dahdi_test.c @@ -0,0 +1,177 @@ +/* + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dahdi_tools_version.h" + +#define SIZE 8000 + +static int verbose; +static int pass = 0; +static float best = 0.0; +static float worst = 100.0; +static double total = 0.0; +static double total_time = 0.0; +static double total_count = 0.0; + +static inline float _fmin(float a, float b) +{ + return (a < b) ? a : b; +} + +static double calculate_accuracy(double count, double ms) +{ + return ((count - _fmin(count, fabs(count - ms))) / count) * 100.0; +} + +void hup_handler(int sig) +{ + double accuracy = calculate_accuracy(total_count, total_time); + printf("\n--- Results after %d passes ---\n", pass); + printf("Best: %.3f%% -- Worst: %.3f%% -- Average: %f%%\n", + best, worst, pass ? total/pass : 100.00); + printf("Cummulative Accuracy (not per pass): %0.3f\n", + pass ? accuracy : 0.0); + exit(0); +} + +static void usage(char *argv0) +{ + char *c; + c = strrchr(argv0, '/'); + if (!c) + c = argv0; + else + c++; + fprintf(stderr, + "Usage: %s [-c COUNT] [-v]\n" + " Valid options are:\n" + " -c COUNT Run just COUNT cycles (otherwise: forever).\n" + " -v More verbose output.\n" + " -h This help text.\n" + , c); +} + +int main(int argc, char *argv[]) +{ + int fd; + int res; + int c; + int count = 0; + int seconds = 0; + int curarg = 1; + char buf[8192]; + float ms; + struct timeval start, now; + fd = open("/dev/dahdi/pseudo", O_RDWR); + if (fd < 0) { + fprintf(stderr, "Unable to open dahdi interface: %s\n", strerror(errno)); + exit(1); + } + + while ((c = getopt(argc, argv, "c:hv")) != -1) { + switch(c) { + case 'c': + seconds = atoi(optarg); + break; + case 'h': + usage(argv[0]); + exit(0); + break; + case '?': + usage(argv[0]); + exit(1); + break; + case 'v': + verbose++; + break; + } + } + while (curarg < argc) { + if (!strcasecmp(argv[curarg], "-v")) + verbose++; + if (!strcasecmp(argv[curarg], "-c") && argc > curarg) + seconds = atoi(argv[curarg + 1]); + curarg++; + } + printf("Opened pseudo dahdi interface, measuring accuracy...\n"); + signal(SIGHUP, hup_handler); + signal(SIGINT, hup_handler); + signal(SIGALRM, hup_handler); + /* Flush input buffer */ + for (count = 0; count < 4; count++) + res = read(fd, buf, sizeof(buf)); + count = 0; + ms = 0; /* Makes the compiler happy */ + if (seconds > 0) + alarm(seconds + 1); /* This will give 'seconds' cycles */ + for (;;) { + if (count == 0) + ms = 0; + gettimeofday(&start, NULL); + res = read(fd, buf, sizeof(buf)); + if (res < 0) { + fprintf(stderr, "Failed to read from pseudo interface: %s\n", strerror(errno)); + exit(1); + } + count += res; + gettimeofday(&now, NULL); + ms += (now.tv_sec - start.tv_sec) * 8000; + ms += (now.tv_usec - start.tv_usec) / 125.0; + if (count >= SIZE) { + const double percent = calculate_accuracy(count, ms); + if (verbose) { + printf("\n%d samples in %0.3f system clock sample intervals (%.3f%%)", + count, ms, percent); + } else if (pass > 0 && (pass % 8) == 0) { + printf("\n"); + } + if (percent > best) + best = percent; + if (percent < worst) + worst = percent; + if (!verbose) + printf("%.3f%% ", percent); + total += percent; + fflush(stdout); + total_count += count; + total_time += ms; + count = 0; + pass++; + } + } +} diff --git a/dahdi_tool.c b/dahdi_tool.c new file mode 100644 index 0000000..a814931 --- /dev/null +++ b/dahdi_tool.c @@ -0,0 +1,541 @@ +/* + * Configuration program for Zapata Telephony Interface + * + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2010 Digium, Inc. + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +/*** MODULEINFO + newt + ***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "dahdi_tools_version.h" + +static int ctl = -1; +static int span_max_chan_pos; + +static struct dahdi_spaninfo s[DAHDI_MAX_SPANS]; + +static char *dahdi_txlevelnames[] = { +"0 db (CSU)/0-133 feet (DSX-1)", +"133-266 feet (DSX-1)", +"266-399 feet (DSX-1)", +"399-533 feet (DSX-1)", +"533-655 feet (DSX-1)", +"-7.5db (CSU)", +"-15db (CSU)", +"-22.5db (CSU)" +} ; + +static char *alarmstr(int span) +{ + static char alarms[80]; + strcpy(alarms, ""); + if (s[span].alarms > 0) { + if (s[span].alarms & DAHDI_ALARM_BLUE) + strcat(alarms,"Blue Alarm/"); + if (s[span].alarms & DAHDI_ALARM_YELLOW) + strcat(alarms, "Yellow Alarm/"); + if (s[span].alarms & DAHDI_ALARM_RED) + strcat(alarms, "Red Alarm/"); + if (s[span].alarms & DAHDI_ALARM_LOOPBACK) + strcat(alarms,"Loopback/"); + if (s[span].alarms & DAHDI_ALARM_RECOVER) + strcat(alarms,"Recovering/"); + if (s[span].alarms & DAHDI_ALARM_NOTOPEN) + strcat(alarms, "Not Open/"); + if (!strlen(alarms)) + strcat(alarms, "/"); + if (strlen(alarms)) { + /* Strip trailing / */ + alarms[strlen(alarms)-1]='\0'; + } + } else + strcpy(alarms, "No alarms."); + return alarms; +} + +static char *getalarms(int span, int err) +{ + int res; + static char tmp[256]; + char alarms[50]; + s[span].spanno = span; + res = ioctl(ctl, DAHDI_SPANSTAT, &s[span]); + if (res) { + if (err) + fprintf(stderr, "Unable to get span info on span %d: %s\n", span, strerror(errno)); + return NULL; + } + strcpy(alarms, ""); + if (s[span].alarms > 0) { + if (s[span].alarms & DAHDI_ALARM_BLUE) + strcat(alarms,"BLU/"); + if (s[span].alarms & DAHDI_ALARM_YELLOW) + strcat(alarms, "YEL/"); + if (s[span].alarms & DAHDI_ALARM_RED) + strcat(alarms, "RED/"); + if (s[span].alarms & DAHDI_ALARM_LOOPBACK) + strcat(alarms,"LB/"); + if (s[span].alarms & DAHDI_ALARM_RECOVER) + strcat(alarms,"REC/"); + if (s[span].alarms & DAHDI_ALARM_NOTOPEN) + strcat(alarms, "NOP/"); + if (!strlen(alarms)) + strcat(alarms, "UUU/"); + if (strlen(alarms)) { + /* Strip trailing / */ + alarms[strlen(alarms)-1]='\0'; + } + } else { + if (s[span].numchans) + strcpy(alarms, "OK"); + else + strcpy(alarms, "UNCONFIGURED"); + } + + snprintf(tmp, sizeof(tmp), "%-15s %s", alarms, s[span].desc); + return tmp; +} + +static void add_cards(newtComponent spans) +{ + int x; + char *s; + void *prev=NULL; + + if (spans) + prev = newtListboxGetCurrent(spans); + newtListboxClear(spans); + for (x=0;x -1)) { + if (zp.rxbits & DAHDI_ABIT) + rabits[zp.chanpos - 1] = '1'; + else + rabits[zp.chanpos - 1] = '0'; + if (zp.rxbits & DAHDI_BBIT) + rbbits[zp.chanpos - 1] = '1'; + else + rbbits[zp.chanpos - 1] = '0'; + + if (zp.rxbits & DAHDI_CBIT) + rcbits[zp.chanpos - 1] = '1'; + else + rcbits[zp.chanpos - 1] = '0'; + if (zp.rxbits & DAHDI_DBIT) + rdbits[zp.chanpos - 1] = '1'; + else + rdbits[zp.chanpos - 1] = '0'; + + if (zp.txbits & DAHDI_ABIT) + tabits[zp.chanpos - 1] = '1'; + else + tabits[zp.chanpos - 1] = '0'; + if (zp.txbits & DAHDI_BBIT) + tbbits[zp.chanpos - 1] = '1'; + else + tbbits[zp.chanpos - 1] = '0'; + if (zp.txbits & DAHDI_CBIT) + tcbits[zp.chanpos - 1] = '1'; + else + tcbits[zp.chanpos - 1] = '0'; + if (zp.txbits & DAHDI_DBIT) + tdbits[zp.chanpos - 1] = '1'; + else + tdbits[zp.chanpos - 1] = '0'; + } else { + c = '-'; + if (!zp.sigtype) + c = ' '; + tabits[zp.chanpos - 1] = c; + tbbits[zp.chanpos - 1] = c; + tcbits[zp.chanpos - 1] = c; + tdbits[zp.chanpos - 1] = c; + rabits[zp.chanpos - 1] = c; + rbbits[zp.chanpos - 1] = c; + rcbits[zp.chanpos - 1] = c; + rdbits[zp.chanpos - 1] = c; + } + if (zp.rxisoffhook) + use++; + } + } + } + snprintf(tmp, sizeof(tmp), "%s\n%s\n%s\n%s\n\n%s\n%s\n%s\n%s", tabits, tbbits,tcbits,tdbits,rabits,rbbits,rcbits,rdbits); + newtTextboxSetText(bitbox, tmp); + sprintf(tmp, "%3d/%3d/%3d", s[span].totalchans, s[span].numchans, use); + newtTextboxSetText(inuse, tmp); + sprintf(tmp, "%s/", dahdi_txlevelnames[s[span].txlevel]); + strcat(tmp, dahdi_txlevelnames[s[span].rxlevel]); + sprintf(tmp, "%3d/%3d", s[span].txlevel, s[span].rxlevel); + newtTextboxSetText(levels, tmp); + sprintf(tmp, "%7d", s[span].bpvcount); + newtTextboxSetText(bpvcount, tmp); + sprintf(tmp, "%7d", s[span].irqmisses); + newtTextboxSetText(irqmisses, tmp); + newtTextboxSetText(alarms, alarmstr(span)); + if (s[span].syncsrc > 0) + strcpy(tmp, s[s[span].syncsrc].desc); + else + strcpy(tmp, "Internally clocked"); + newtTextboxSetText(syncsrc, tmp); + + +} + +static newtComponent spans; +static void show_span(int span) +{ + newtComponent form; + newtComponent back; + newtComponent label; + newtComponent bitbox; + newtComponent inuse; + newtComponent levels; + newtComponent bpvcount; + newtComponent alarms; + newtComponent syncsrc; + newtComponent irqmisses; + + char s1[] = " 1111111111222222222233"; + char s2[] = "1234567890123456789012345678901"; + int x; + struct newtExitStruct es; + + void *ss; + char info2[256]; + + if (span < 0) { + /* Display info on a span */ + ss = newtListboxGetCurrent(spans); + if (ss) { + span = (long)(ss); + } + } + + snprintf(info2, sizeof(info2), "%-59s F10=Back", s[span].desc); + newtCenteredWindow(60,20, s[span].desc); + newtPushHelpLine(info2); + + back = newtButton(48,8,"Back"); + form = newtForm(NULL, NULL, 0); + + newtFormAddComponents(form, back, NULL); + + span_max_chan_pos = s[span].totalchans; + for (x=0;x span_max_chan_pos ) + span_max_chan_pos = zp.chanpos; + } + + if (span_max_chan_pos > 32) + span_max_chan_pos = 32; + + s1[span_max_chan_pos] = '\0'; + s2[span_max_chan_pos] = '\0'; + + bitbox = newtTextbox(8,10,span_max_chan_pos,9,0); + newtFormAddComponent(form, bitbox); + + label = newtLabel(8,8,s1); + newtFormAddComponent(form, label); + + label = newtLabel(8,9,s2); + newtFormAddComponent(form, label); + + newtFormAddHotKey(form, NEWT_KEY_F10); + newtFormSetTimer(form, 200); + + label = newtLabel(4,10,"TxA"); + newtFormAddComponent(form, label); + + label = newtLabel(4,11,"TxB"); + newtFormAddComponent(form, label); + + label = newtLabel(4,12,"TxC"); + newtFormAddComponent(form, label); + + label = newtLabel(4,13,"TxD"); + newtFormAddComponent(form, label); + + label = newtLabel(4,15,"RxA"); + newtFormAddComponent(form, label); + + label = newtLabel(4,16,"RxB"); + newtFormAddComponent(form, label); + + label = newtLabel(4,17,"RxC"); + newtFormAddComponent(form, label); + + label = newtLabel(4,18,"RxD"); + newtFormAddComponent(form, label); + + + label = newtLabel(4,7,"Total/Conf/Act: "); + newtFormAddComponent(form, label); + + inuse = newtTextbox(24,7,12,1,0); + newtFormAddComponent(form, inuse); + + label = newtLabel(4,6,"Tx/Rx Levels: "); + newtFormAddComponent(form, label); + + levels = newtTextbox(24,6,30,1,0); + newtFormAddComponent(form, levels); + + label = newtLabel(4,5,"Bipolar Viol: "); + newtFormAddComponent(form, label); + + bpvcount = newtTextbox(24,5,30,1,0); + newtFormAddComponent(form, bpvcount); + + label = newtLabel(4,4,"IRQ Misses: "); + newtFormAddComponent(form, label); + + irqmisses = newtTextbox(24,4,30,1,0); + newtFormAddComponent(form, irqmisses); + + label = newtLabel(4,3,"Sync Source: "); + newtFormAddComponent(form, label); + + syncsrc = newtTextbox(24,3,30,1,0); + newtFormAddComponent(form, syncsrc); + + label = newtLabel(4,2,"Current Alarms: "); + newtFormAddComponent(form, label); + + alarms = newtTextbox(24,2,30,1,0); + newtFormAddComponent(form, alarms); + + for(;;) { + /* Wait for user to select something */ + do { + add_cards(NULL); + show_bits(span, bitbox, inuse, levels, bpvcount, alarms, syncsrc, irqmisses); + newtFormRun(form, &es); + } while(es.reason == NEWT_EXIT_TIMER); + switch(es.reason) { + case NEWT_EXIT_COMPONENT: + if (es.u.co == back) { + goto out; + } + break; + case NEWT_EXIT_HOTKEY: + switch(es.u.key) { +#if 0 + case NEWT_KEY_F1: + show_span(-1); + break; +#endif + case NEWT_KEY_F10: + goto out; + } + break; + default: + break; + } + } + +out: + newtFormDestroy(form); + newtPopWindow(); + newtPopHelpLine(); + span_max_chan_pos = 0; +} + +static void show_spans(void) +{ + newtComponent form; + newtComponent quit; + newtComponent label; + newtComponent sel; + + + struct newtExitStruct es; + + + quit = newtButton(50,14,"Quit"); + sel = newtButton(10,14,"Select"); + + spans = newtListbox(5, 2, 10, NEWT_FLAG_SCROLL); + newtListboxSetWidth(spans, 65); + + label = newtLabel(5,1,"Alarms Span"); + + newtCenteredWindow(72,18, "DAHDI Telephony Interfaces"); + form = newtForm(NULL, NULL, 0); + + newtFormSetTimer(form, 200); + + newtFormAddComponents(form, spans, sel, quit, label, NULL); + + newtComponentAddCallback(spans, sel_callback, NULL); + + newtFormAddHotKey(form, NEWT_KEY_F1); + newtFormAddHotKey(form, NEWT_KEY_F10); + + for(;;) { + /* Wait for user to select something */ + do { + add_cards(spans); + newtFormRun(form, &es); + } while(es.reason == NEWT_EXIT_TIMER); + + switch(es.reason) { + case NEWT_EXIT_COMPONENT: + if (es.u.co == quit) { + /* Quit if appropriate */ + newtFormDestroy(form); + return; + } else if (es.u.co == sel) { + show_span(-1); + } + break; + case NEWT_EXIT_HOTKEY: + switch(es.u.key) { + case NEWT_KEY_F1: + show_span(-1); + break; + case NEWT_KEY_F10: + newtFormDestroy(form); + return; + } + break; + default: + break; + } + } +} + +static void cleanup(void) +{ + newtPopWindow(); +} + +int main(int argc, char *argv[]) +{ + + ctl = open("/dev/dahdi/ctl", O_RDWR); + if (ctl < 0) { + fprintf(stderr, "Unable to open /dev/dahdi/ctl: %s\n", strerror(errno)); + exit(1); + } + newtInit(); + newtCls(); + + newtDrawRootText(0,0,"DAHDI Tool (C)2002-2008 Digium, Inc."); + newtPushHelpLine("Welcome to the DAHDI Tool!"); + show_spans(); + cleanup(); + newtFinished(); + return 0; +} diff --git a/dahdi_tools_version.h b/dahdi_tools_version.h new file mode 100644 index 0000000..b4ec5fb --- /dev/null +++ b/dahdi_tools_version.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2008 Digium, Inc. + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +extern const char dahdi_tools_version[]; diff --git a/dahdi_waitfor_span_assignments b/dahdi_waitfor_span_assignments new file mode 100755 index 0000000..1080d84 --- /dev/null +++ b/dahdi_waitfor_span_assignments @@ -0,0 +1,73 @@ +#! /bin/sh + +usage() { + echo >&2 "Usage: $0 {assigned|unassigned}" + echo >&2 "# wait until all spans known are assigned/unassigned" + exit 1 +} + +TIMEOUT=5 # How much time to wait for spans + +if [ "$#" -lt 1 ]; then + usage +fi +wanted_event="$1" +shift + +case "$wanted_event" in +assigned) + ;; +unassigned) + ;; +*) + usage + ;; +esac + +devbase='/sys/bus/dahdi_devices/devices' + +spans_of() { + dev="$1" + wc -l < "$dev/spantype" +} + +assigned_spans_of() { + dev="$1" + ls -d "$dev/span-"* 2>/dev/null | wc -l +} + + +waitfor_span_assignments() { + wanted_state="$1" + device_list=`ls -d "$devbase/"* 2> /dev/null` + finished='' + count="$TIMEOUT" + echo -n "Waiting for spans to become $wanted_state: " + while [ "$count" -gt 0 ]; do + finished='yes' + for dev in $device_list + do + spans=`spans_of "$dev"` + assigned_spans=`assigned_spans_of "$dev"` + if [ "$wanted_state" = 'assigned' -a "$assigned_spans" -ne "$spans" ]; then + finished='no' + elif [ "$wanted_state" = 'unassigned' -a "$assigned_spans" -ne 0 ]; then + finished='no' + fi + done + if [ "$finished" = 'yes' ]; then + break + else + sleep 1 + echo -n "." + fi + count=`expr "$count" - 1` + done + if [ "$finished" = 'yes' ]; then + echo "done" + else + echo "timeout" + fi +} + +waitfor_span_assignments "$wanted_event" diff --git a/doc/dahdi_cfg.8 b/doc/dahdi_cfg.8 new file mode 100644 index 0000000..86d96d6 --- /dev/null +++ b/doc/dahdi_cfg.8 @@ -0,0 +1,86 @@ +.TH "DAHDI_CFG" "8" "16 Jun 2008" "" "" + +.SH NAME +dahdi_cfg \- configures DAHDI kernel modules from /etc/dahdi/system.conf +.SH SYNOPSIS + +.B dahdi_cfg [\-c \fICFG_FILE\fB] [\-S\fINUM\fB [\-S\fICHANS\fB]] [\-s] [\-f] [\-t] [\-v [\-v ... ] ] + +.B dahdi_cfg \-h + +.SH DESCRIPTION +.B dahdi_cfg +configures DAHDI interface cards from a config file. + +You generally need to run it with a valid configurations +in order for DAHDI modules to work properly. + +It must be run to configure every DAHDI span. Normally it is run from +the DAHDI init script. + +.SH OPTIONS + +.B \-c \fICFG_FILE +.RS +Use an alternative configuration file instead of +.I /etc/dahdi/system.conf + +If \fICFG_FILE\fR is '\fB\-\fR', it is read from stdin. +.RE + +.B \-C \fICHANNELS +.RS +Only apply changes to channels in the specified range. Only +applicable when \-S is in use. +.RE + +.B \-s +.RS +Only shutdown spans. +.RE + +.B \-S \fISPAN +.RS +Only apply changes to span no. \fISPAN\fR. For a digital span (with +a 'span=' line in the configuration file) this will do. For an analog +span you'll have to explicitly tell dahdi_cfg the range of channels, +using \-C . +.RE + +.B \-f +.RS +Always configure every channel, even if it appears not to have changed. +.RE + +.B \-t +.RS +Test mode. Don't do anything, just report what you wanted to do. +.RE + +.B \-v +.RS +Be more verbose. Add extra v-s for extra verbosity. +.RE + +.B \-h +.RS +Display a brief help message. +.RE + +.SH FILES + +.I /etc/dahdi/system.conf +.RS +The default location for the configuration file. +.RE + +.SH SEE ALSO +dahdi_tool(8), dahdi_monitor(8), asterisk(8). + +.SH AUTHOR +This manual page was written by Santiago Ruano Rinc\['o]n + for +the Debian system (but may be used by others). Permission is +granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. diff --git a/doc/dahdi_diag.8 b/doc/dahdi_diag.8 new file mode 100644 index 0000000..0f01a09 --- /dev/null +++ b/doc/dahdi_diag.8 @@ -0,0 +1,52 @@ +.TH dahdi_diag 8 "2008-01-07" +.SH NAME +dahdi_diag \(em Dump DAHDI channel parameters +.SH SYNOPSIS +.B dahdi_diag +.I channel + +.SH DESCRIPTION +.B dahdi_diag +asks the kernel to dump parameters for DAHDI channel no. +.I channel +to the kernel logs. You will be able to see them using, e.g. dmesg(1). + + +.SH OPTIONS +.I channel +.RS +The number of the DAHDI channel whose parammeters should be dumped. +May be any DAHDI channel (even if it is open). +.RE + +.SH EXAMPLE + + # /tmp/dahdi_diag 5 + # dmesg | tail \-n 15 + Dump of DAHDI Channel 5 (XPP_BRI_TE/00/01/1,5,2): + + flags: 501 hex, writechunk: c5190948, readchunk: c5190954 + rxgain: ccad2e80, txgain: ccad2e80, gainalloc: 0 + span: c48a900c, sig: 80 hex, sigcap: 80 hex + inreadbuf: \-1, outreadbuf: 0, inwritebuf: 0, outwritebuf: \-1 + blocksize: 160, numbufs: 4, txbufpolicy: 0, txbufpolicy: 0 + txdisable: 0, rxdisable: 0, iomask: 0 + curzone: c78e7000, tonezone: 0, curtone: 00000000, tonep: 0 + digitmode: 0, txdialbuf: , dialing: 0, aftdialtimer: 0, cadpos. 0 + confna: 0, confn: 0, confmode: 0, confmute: 0 + ec: 00000000, echocancel: 0, deflaw: 0, xlaw: ccab5e80 + echostate: 00, echotimer: 0, echolastupdate: 0 + itimer: 0, otimer: 0, ringdebtimer: 0 + +.SH SEE ALSO +dahdi_cfg(8), asterisk(8), dmesg(1). + +.SH AUTHOR + +This manual page was written by Tzafrir Cohen +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common\-licenses/GPL. diff --git a/doc/dahdi_maint.8 b/doc/dahdi_maint.8 new file mode 100644 index 0000000..98aad3d --- /dev/null +++ b/doc/dahdi_maint.8 @@ -0,0 +1,62 @@ +.TH "DAHDI_MAINT" "8" "9 Sep 2011" "" "" + +.SH NAME +dahdi_maint \- Sets Dahdi spans into maintenance mode, e.g.: loopback +.SH SYNOPSIS + +.B dahdi_maint \-s \fInum\fB [options] +.B dahdi_maint <\-h|\-\-help> + +.SH DESCRIPTION + +dahdi_maint uses the DAHDI_MAINT interface to set a Dahdi span (port +of a Dahdi adapter card) into loopback mode or similar maintenance mode. + +.SH OPTIONS +.B \-s \-\-span \fInum\fR +.RS +The span number. Required. +.RE + +.B \-l \-\-loopback +.RS +Loopback type. One of: +.IP localhost 4 +loop back towards host +.IP networkline 4 +network line loopback +.IP networkpayload 4 +network payload loopback +.IP loopup 4 +transmit loopup signal +.IP loopdown 4 +transmit loopdown signal +.IP off 4 +end loopback mode +.RE + +.B \-i \-\-insert +.RS +Insert an error of a specific type +.RE + +.SH EXAMPLES +Enable network line loopback on span 1: + + dahdi_maint \-s 1 \-\-loopback networkline + +Disable network line loopback on span 1: + + dahdi_maint \-s 1 \-\-loopback off + + +.SH SEE ALSO +.PP +dahdi_tool(8), dahdi_cfg(8), asterisk(8). + +.SH AUTHOR +.PP +This manual page was written by Tzafrir Cohen . +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU General Public License, Version 2 any later +version published by the Free Software Foundation. diff --git a/doc/dahdi_monitor.8 b/doc/dahdi_monitor.8 new file mode 100644 index 0000000..a0a2f42 --- /dev/null +++ b/doc/dahdi_monitor.8 @@ -0,0 +1,145 @@ +.TH "DAHDI_MONITOR" "8" "9 Sep 2011" "" "" + +.SH NAME +dahdi_monitor \- checks the Rx/Tx levels of a DAHDI channels +.SH SYNOPSIS + +.B dahdi_monitor \fInum\fB [\-v[v]] +.B dahdi_monitor \fInum\fB [\-o] [<\-f|\-F> \fIFILE\fB] +.B dahdi_monitor \fInum\fB [[<\-r|\-R> \fIFILE\fB]] [[<\-t|\-T> \fIFILE\fB]] + +.SH DESCRIPTION + +dahdi_monitor monitors a Dahdi channel. It can record the output to a +file, play it to the speaker, or visualize the audio levels on the +terminal. + +Recorded audio files are by default raw signed linear PCM. If the file +name ends with ".wav", the recorded file will be a WAV file. + +The visual display shows the current audio level at both the Rx +(audio Received by Asterisk) and +Tx (audio Transmitted by Asterisk) + +To exit the program, press Ctrl-C. + +.SH OPTIONS +The first (mandatory) parameter is the number of the channel +to monitor. + +.B \-m +.RS +Multiple channels. Don't multiplex both Rx and Tx in a single channel. +Normally there's a different option that you need that implies it. +.RE + +.B \-o +.RS +Plays the output to OSS (/dev/dsp). Requires \-m not to be used. +.RE + +.B \-v +.RS +Display Visual audio levels. With two v-s, Verbose mode is enabled, that +shows the actual levels as numbers. Note that this requires a terminal +wider than 80 columns to be properly displayed. + +Implies \-m. +.RE + +.B \-f \fIFILE +.RS +Record the content of the channel (Tx + Rx) to a file. +.RE + +.B \-F \fIFILE +.RS +Record the content of the channel (Tx + Rx) before the echo canceler +to a file. +.RE + +.B \-r \fIFILE +.RS +Record the content of the Rx channel to a file. + +Implies \-m. +.RE + +.B \-R \fIFILE +.RS +Record the content of the R channel before the echo canceler to a file. + +Implies \-m. +.RE + +.B \-s \fIFILE +.RS +Record the content of the Tx and Rx of the channel to a file. +.RE + +.B \-S \fIFILE +.RS +Records a stereo of both Tx and Rx of the channel before the echo +canceler to a file. +.RE + +.B \-t \fIFILE +.RS +Record the content of the Tx channel to a file. + +Implies \-m. +.RE + +.B \-T \fIFILE +.RS +Record the content of the Tx channel before the echo canceler to a file. + +Implies \-m. +.RE + +.SH EXAMPLES + +Visualize audio levels on DAHDI channel 2: + + dahdi_monitor 2 \-v + + +Record channel 3 to a file: + + dahdi_monitor 3 \-f output.raw + +This will create a raw PCM file (signed-linear, 8kHz, mono, 16 bits per +sample). Both the Tx and Rx will be multiplexed in a single channel. +It can be converted to a WAV file using e.g.: + + sox \-s \-c1 \-2 \-r8000 output.raw output.wav + + +Record Tx and Rx of channel 5 to separate files. This time directly to +WAV files: + + dahdi_monitor 5 \-r output_rx.wav \-t output_tx.wav + + +Record channel 8 to a stereo file (Tx and Rx on its two channels): + + dahdi_monitor 8 \-s output.raw + +Converting it to a WAV file: + + sox \-s \-c2 \-2 \-r8000 output.raw output.wav + + + +.SH SEE ALSO +.PP +dahdi_tool(8), dahdi_cfg(8). + +.SH AUTHOR +.PP +This manual page was written by Santiago Ruano Rinc\['o]n + for +the Debian system (but may be used by others). Permission is +granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. diff --git a/doc/dahdi_scan.8 b/doc/dahdi_scan.8 new file mode 100644 index 0000000..d7a9e16 --- /dev/null +++ b/doc/dahdi_scan.8 @@ -0,0 +1,101 @@ +.TH dahdi_scan 8 "2008-03-18" +.SH NAME +dahdi_scan \(em Print Configuration of DAHDI Spans +.SH SYNOPSIS +.B dahdi_scan +.I [spans] + +.SH DESCRIPTION +.B dahdi_scan +prints information about DAHDI spans in the system. For analog spans it +also provides a list of channels. + +By default it prints information about all the spans in the system. +However if parameters are provided, they will be considered to be a list +of span numbers and information will be printed for them. + +Output is printed to the standard output. The format is that of an +Asterisk configuration file (similar to a "ini" configuration file), +where the name of the section is the number of the span. Note that the +specifically for analog spans some keys may appear more than once, and +hence you can not use a parser for an "ini" format and assume you have a +dictionary. + +.SH EXAMPLES +Printing information for spans 1, 2 and 4: + + dahdi_scan 1 2 4 + +And to print all the spans: + + dahdi_scan + +Information about a certain analog span: + + [5] + active=yes + alarms=OK + description=Xorcom XPD #00/10: FXS + name=XBUS\-00/XPD\-10 + manufacturer=Xorcom Inc. + devicetype=Astribank: Unit 1 Subunit 0: FXS + location=usb\-0000:00:03.3\-4 + basechan=125 + totchans=8 + irq=0 + type=analog + port=125,FXS + port=126,FXS + port=127,FXS + port=128,FXS + port=129,FXS + port=130,FXS + port=131,FXS + port=132,FXS + +And an example of a digital span: + + [1] + active=yes + alarms=RED + description=T2XXP (PCI) Card 0 Span 1 + name=TE2/0/1 + manufacturer=Digium + devicetype=Wildcard TE205P (4th Gen) + location=Board ID Switch 0 + basechan=1 + totchans=24 + irq=193 + type=digital\-T1 + syncsrc=0 + lbo=0 db (CSU)/0\-133 feet (DSX\-1) + coding_opts=B8ZS,AMI + framing_opts=ESF,D4 + coding=B8ZS + framing=ESF + +The "type" field may contain: "analog", "digital\-T1", "digital\-E1", +"digital\-J1" or "digital\-BRI". + +.SH FILES +Requires read access to /dev/dahdi/ctl . + +.SH SEE ALSO +dahdi_cfg(8), asterisk(8). + +.SH BUGS +The program still does not do everything described in the man page. + +It also assumes that spans don't skip channel numbers, and that their +channel numbers are "running". This is anyway almost always the case. +And always the case in a normal boot process. + +.SH AUTHOR + +This manual page was written by Tzafrir Cohen +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common\-licenses/GPL. diff --git a/doc/dahdi_span_assignments.8 b/doc/dahdi_span_assignments.8 new file mode 100644 index 0000000..52e0391 --- /dev/null +++ b/doc/dahdi_span_assignments.8 @@ -0,0 +1,251 @@ +.TH "DAHDI_SPAN_ASSIGNMENTS" "8" "23 Jan 2014" "" "" + +.SH NAME +dahdi_span_assignments \- handle DAHDI spans assignments +.SH SYNOPSIS + +.B dahdi_span_assignments [\-v|\-\-verbose] [\-n|\-\-dry\-run] \fB[\fIdevpath\fB...] + +.B dahdi_span_assignments [\-v|\-\-verbose] list \fB[\fIdevpath\fB...] + +.B dahdi_span_assignments [\-v|\-\-verbose] [\-k|\-\-key \fIkey\fB] dumpconfig + +.B dahdi_span_assignments \-h|\-\-help + +.SH DESCRIPTION +Channels in DAHDI devices (such as DAHDI PCI cards) are groups to logical +units called "spans" (for example: a port in a digital card is a span). +When the kernel module parameter \fBdahdi.auto_assign_span\fR is unset, +DAHDI devices that register with DAHDI don't cause their spans to be +automatically assigned. + +This allows user-space to order DAHDI to assign them to specific span +and channel numbers. That way, specific spans on specific DAHDI devices +may be assigned with specific span and channel numbers \fBregardless\fR +of the registration order of the hardware (or if all hardware is present +at all). + +.B dahdi_span_assignments +is used to assign those spans or to help creating the configuration +file used in their assignment: +.B /etc/dahdi/assigned\-spans.conf . + +.SH SUB-COMMANDS + +There are several sub-commands. + +All sub-commands take an optional list of paths to SysFS nodes of +devices. If given, the command will only operate on those DAHDI +devices. The default is to operate on all devices (which would normally +be the sane case when running from the command-line). + +.B add \fB[\fIdevpath \fB...] +.RS +Applies to all devices or to those listed on the command line. +Parameters are paths (in SysFS) to DAHDI devices with unassigned +spans. + +The command will assign spans with DAHDI according to +configuration in \fBassigned\-spans.conf\fR. + +If no line matches the span, or if the assignment for it fails (it is +not available) it will remain unassigned. + +If any of the span settings fails (the span number or range of channels +is already in use), the program will print a message, but continue +applying the others. In such a case you should fix assigned\-spans.conf +and re-run \fBadd\fR (or run \fBauto\fR to give those channels the +first available range and regenerate the file with 'dahdi_genconf +assignedspans'). +.RE + +.B remove \fB[\fIdevpath \fB...] +.RS +Applies to all devices or to those listed on the command line. +Parameters are paths (in SysFS) to DAHDI devices with assigned +spans. + +The command will un-assign them. +.RE + +.B auto \fB[\fIdevpath \fB...] +.RS +Applies to all devices or to those listed on the command line. +Parameters are paths (in SysFS) to DAHDI devices with unassigned +spans. + +Each span is assigned to first available span number and channel +numbers, as if \fBdahdi.auto_assign_span\fR was set. The configuration +file doesn't affect these assignments. +.RE + +.B list +.RS +List all spans in the system. +.RE + +.B dumpconfig +.RS +List all assigned spans in the system in a format fit to be used in +\fBassigned\-spans.conf\fR. Use this to generate a configuration file after +you have (automatically or manually) assigned all existing spans. + +.B dahdi_genconf assignedspans +uses this command internally. +.RE + +.SH OPTIONS + +.B \-v \-\-verbose +.RS +Verbose output. +.RE + +.B \-n \-\-dry\-run +.RS +Don't assign / un-assign spans. Only print commands used to do so. +.RE + +.B \-k \fIkey +.RS +For \fBdumpconfig\fR \- The key by which to identify the hardware in the +generated configuration. Legal values: + +.B hwid +.RS +Hardware identifier (e.g.: software-readable serial number). This is the +default. If the device has no hwid, devpath is used. +.RE + +.B location +.RS +The location field (file) in the SysFS device node (directory) for the +DAHDI device. If not available (typically: DAHDI version <= 2.7.x), +devpath is used. +.RE + +.B devpath +.RS +Path in SysFS to the device node. +.RE +.RE + +.SH CONFIGURATION +.B /etc/dahdi/assigned\-spans.conf +is a file with lines specifying assignment of spans. + +Empty lines or lines beginning with '#' are ignored. + +Each line is in the format of: + +.I ID spanspec ... + +The \fIID\fR field specifies the DAHDI device and the \fIspanspecs\fR +define how to assign its spans. A line may have multiple +\fIspanspecs\fR in a single line (though dumpconfig generates a +configuration with one per line). + +.SS Span Identifier +A DAHDI device may be specified either by a hardware identifier (a +software readable serial number or whatever) or the location in which +it is installed on the system. The former makes it simpler to change +connector / slot whereas the latter makes it simpler to replace a unit. + +The value in this field is matched (when the commands \fBadd\fR and +\fBremove\fR) are used) to the following values: + + \fIhwid\fR + \fB@\fIlocation\fR + \fIdevpath\fR + +See above for their descriptions. The value may include shell wildcards: +*, ? and [], which are used in the match. The values to be matched are +first cleaned up: '!' is replaced with '/' and any character beyond +"a\-zA\-Z0\-9/:.\-" is removed. + +.SS Span Specification + +Each line should have one or more span specifications: this is the value +used to assign a span with DAHDI in the SysFS interface. A +specification has three colon-separated numbers: + +.I rel_span_no:span_no:first_chan + +for instance, the following are four span specifications for a quad-E1 +device: 1:6:53 2:7:84 3:8:115 4:9:146 occupying spans 6-9 and channels +53-176. + +.B rel_span_no +.RS +The relative number of the span in the device. E.g.: port number. +.RE + +.B span_no +.RS +The desired DAHDI span number. Must be available. +.RE + +.B first_chan +.RS +The desired DAHDI channel number for the first DAHDI channel in the span. +All channels of the span will be assigned following it and hence that +space must be available. +.RE + + +.SH ENVIRONMENT + +.B DAHDICONFDIR +.RS +The directory in which assigned\-spans.conf resides. /etc/dahdi if not +overridden from the environment. +.RE + +.B DAHDISASSIGNEDSPANSCONF +.RS +The path to assigned-spans.conf resides. /etc/dahdi/assigned\-spans.conf if +not overridden from the environment. +.RE + +.B SPAN_ASSIGNMENTS_KEY +.RS +The default value for \-k . Defaults to "hwid" if not overridden from the +environment. +.RE + + +.SH FILES + +.B /etc/dahdi/assigned\-spans.conf +.RS +The default location for the configuration file. +.RE + +.B /sys/bus/dahdi_devices/devices/\fIdevice\fR +.RS +SysFS node for the device. In this directory reside the following +files, among others: + +.B location +.RS +The value of the device's location field. +.RE + +.B assign_span, unassign_span, auto_assign +.RS +Write only files for the operations. Used by \fBadd\fR, \fBremove\fR and +\fBauto\fR, respectively. +.RE + +.RE + +.SH SEE ALSO +dahdi_span_types(8), dahdi_genconf(8), dahdi_cfg(8) + +.SH AUTHOR +dahdi_span_assignments was written by Oron Peled. This manual page was +written by Tzafrir Cohen. Permission is granted to copy, distribute +and/or modify this document under the terms of the GNU General Public +License, Version 2 any later version published by the Free Software +Foundation. + diff --git a/doc/dahdi_span_types.8 b/doc/dahdi_span_types.8 new file mode 100644 index 0000000..4aba1a9 --- /dev/null +++ b/doc/dahdi_span_types.8 @@ -0,0 +1,197 @@ +.TH "DAHDI_SPAN_TYPES" "8" "23 Jan 2014" "" "" + +.SH NAME +dahdi_span_types \- set line modes of DAHDI spans before assignment +.SH SYNOPSIS + +.B dahdi_span_types [\fIoptions\fB] \fB[\fIdevpath \fB...] + +.SH DESCRIPTION +The span type (the line mode: E1/T1/J1) must be set to a span before +DAHDI assigns it a span number, as E1 spans use more channels. +\fBdahdi_span_types\fR applies the span type configuration to an +un-assigned span. + +Using it only makes sense when the kernel module parameter +\fBdahdi.auto_assign_span\fR is unset, otherwise DAHDI automatically +assign span numbers during device registration. + +.B dahdi_span_types +takes a command and an optional list of devices. If no device is given, +the command is applied to all devices. + +The device is marked as a path in the SysFS tree. + +.SH OPTIONS + +.B \-h|\-\-help +.RS +Output usage message and exit +.RE + +.B \-n|\-\-dry\-run +.RS +During \fB"set"\fR operation, only show what would be done, without actually +changing anything. +.RE + +.B \-v|\-\-verbose +.RS +During \fB"set"\fR operation, show the actions that are being performed. +.RE + +.BI \-\-line\-mode= +.RS +During \fB"dumpconfig"\fR operation, force special generation mode: +.IP \(bu 3 +First, generates a "wildcard" entry with the fiven \fBline\-mode\fR. +.IP \(bu 3 +Comment out all span entries. Each of them may be manually un-commented +to override the "wildcard". +.RE + +.SH SUB-COMMANDS +.B set +.RS +Reads settings from \fBspan\-types.conf\fR and applies them to the +device(s) specified in the command line (or all devices, if none +specified). +.RE + +.B list +.RS +List line modes for all spans in the system which may be set with +dahdi_span_types (E1/T1/J1 spans). +.RE + +.B dumpconfig +.RS +List types for the spans in a format fit to be used in +\fBspan\-types.conf\fR. Use this to generate a configuration file after +you have (perhaps manually) set all existing spans. + +.B dahdi_genconf spantypes +uses this command internally. +.RE + +.SH CONFIGURATION +.SS General structure +.B span\-types.conf +is a file with lines specifying line modes of spans. + +Empty lines or lines beginning with '#' are ignored. + +Each line is in the format of: + +.I ID spanspec ... + +The \fIID\fR field specifies the DAHDI device and the \fIspanspecs\fR +define the line modes of its spans. A line may have multiple +\fIspanspecs\fR in a single line (though dumpconfig generates a +configuration with one per line). + +.SS Span Identifier +A DAHDI device may be specified either by a hardware identifier (a +software readable serial number or whatever) or the location in which +it is installed on the system. The former makes it simpler to change +connector / slot whereas the latter makes it simpler to replace a unit. + +The value in this field is matched (when the command \fBset\fR is +used) to the following values: + + \fIhwid\fR + \fB@\fIlocation\fR + \fIdevpath\fR + +See above for their descriptions. The value may include shell wildcards: +*, ? and [], which are used in the match. The values to be matched are +first cleaned up: '!' is replaced with '/' and any character not in +"a\-zA\-Z0\-9/:.\-" is replaced by "_". + +Note that while span\-types.conf allows an arbitrarily-complex +combination of E1, J1 and T1 ports, it would normally have just a single +wildcard line setting the line mode (the first line in the example below). + +.SS Span Specification + +Each line should have one or more span specifications: this is the value +used to set span type with DAHDI in the SysFS interface. A +specification has two colon-separated fields: + +.I rel_span_no:span_type + +for instance, the following are four span specifications specify ports 1 +and 2 as E1 and ports 3 and 4 as T1: [12]:E1 [34]:T1 . + +.B rel_span_no +.RS +The relative number of the span in the device. E.g.: port number. +This field may contain shell wildcards (*, ? and []) +.RE + +.B span_type +.RS +E1/T1/J1 +.RE + +.SS Multiple matches +During \fBset\fR operation, the \fBdahdi_span_types\fR applies all +matching settings to a span. This is done in the order of lines in the +configuration files. + +Thus, if there are multiple matches to a span -- the last match +will \fIwin\fR (all will be applied to the kernel in order. The last +one in the file will be applied last). + +Example: +.EX +* *:T1 # All spans on all devices will be T1 +usb:X1234567 [34]:E1 # Except spans 3,4 on the device which will be E1 +.EE + + +.SH ENVIRONMENT + +.B DAHDICONFDIR +.RS +The directory in which span\-types.conf resides. /etc/dahdi if not +overridden from the environment. +.RE + +.B DAHDISPANTYPESCONF +.RS +The path to span\-types.conf resides. /etc/dahdi/span\-types.conf if +not overridden from the environment. +.RE + + +.SH FILES + +.B /etc/dahdi/span\-types.conf +.RS +The default location for the configuration file. +.RE + +.B /sys/bus/dahdi_devices/devices/\fIdevice\fR +.RS +SysFS node for the device. In this directory reside the following +files, among others: + +.B spantype +.RS +read/write file. Reading from it returns current configuration for spans +of the device. Span-specifications can be written to it to change line +modes (but only for a span that is not assigned yet). +.RE + + +.SH SEE ALSO +dahdi_span_assignments(8), dahdi_genconf(8), dahdi_cfg(8) + +.SH AUTHOR +dahdi_span_types was written by Oron Peled. This manual page was +written by Tzafrir Cohen. Permission is granted to copy, distribute +and/or modify this document under the terms of the GNU General Public +License, Version 2 any later version published by the Free Software +Foundation. + diff --git a/doc/dahdi_test.8 b/doc/dahdi_test.8 new file mode 100644 index 0000000..90b1e0b --- /dev/null +++ b/doc/dahdi_test.8 @@ -0,0 +1,49 @@ +.TH dahdi_test 8 "2005-06-25" +.SH "NAME" +dahdi_test \(em Test if the DAHDI timer provides timely response +.SH "SYNOPSIS" +.B dahdi_test +.I [ \-v ] + +.SH DESCRIPTION +.B dahdi_test +dahdi_test runs a timing test in a loop and prints the result of each loop. +The test is as follows: + +It reads 8192 bytes from the DAHDI timer device (\fI/dev/dahdi/pseudo\fR). +This should take exactly 8000 ms . It uses calls to +.I gettimeofday(2) +before and after that read to check that indeed exactly 8000ms have passed. + +Values of 100% and 99.99% Are normally considered a definite +.I pass. +Values of 99.98% and 99.97% are probably OK as well. + +.SH OPTIONS +.B \-v +.RS +Be more verbose: print one line per test. +.RE + +.B \-c +.I count +.RS +Run for +.I count +times instead of running forever. +.RE + +.SH FILES +.B /dev/dahdi/pseudo +.RS +.RE +The device file used to access the DAHDI timer. + +.SH SEE ALSO +dahdi_tool(8), dahdi_cfg(8), asterisk(8). gettimeofday(2) + +.SH AUTHOR +This manual page was written by Tzafrir Cohen +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. diff --git a/doc/dahdi_tool.8 b/doc/dahdi_tool.8 new file mode 100644 index 0000000..2777366 --- /dev/null +++ b/doc/dahdi_tool.8 @@ -0,0 +1,25 @@ +.TH "DAHDI_TOOL" "8" "16 June 2008" "" "" + +.SH NAME +dahdi_tool \- Shows status of DAHDI interfaces +.SH SYNOPSIS + +.B dahdi_tool + +.SH DESCRIPTION +dahdi_tool shows the current status the DAHDI inteface cards plugged +to the computer. + +It displays values like Current Alarms, SyncSource, Tx/Rx +Levels for each DAHDI interface. + +.SH SEE ALSO +dahdi_monitor(8), asterisk (8). + +.SH AUTHOR +This manual page was written by Santiago Ruano Rinc\['o]n + for +the Debian system (but may be used by others). Permission is +granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. diff --git a/doc/dahdi_waitfor_span_assignments.8 b/doc/dahdi_waitfor_span_assignments.8 new file mode 100644 index 0000000..6aaa0b9 --- /dev/null +++ b/doc/dahdi_waitfor_span_assignments.8 @@ -0,0 +1,49 @@ +.TH "DAHDI_WAITFOR_SPAN_ASSIGNMENTS" "8" "22 Jan 2014" "" "" + +.SH NAME +dahdi_waitfor_span_assignments \- wait for DAHDI spans to get (un)assigned +.SH SYNOPSIS + +.B dahdi_span_assignments assigned + +.B dahdi_span_assignments unassigned + +.SH DESCRIPTION +DAHDI spans get assigned / unassigned asynchronously. + +.B dahdi_span_assignments +is a helper script that allows running commands after all the spans have +been assigned or unassigned. + +It takes a single command: \fBassigned\fR or \fBunassigned\fR and waits +(up until a timeout of 5 seconds) for all the DAHDI spans in the system +to do so. + +Note that if the system has a span that will not get assigned +automatically (e.g.: it's not in assigned\-spans.conf), this program +does not know and will wait until a timeout. + +.SH EXAMPLES + + modprobe wctdm24xxp + dahdi_waitfor_span_assignments assigned + do_something + + dahdi_span_assignments add + dahdi_waitfor_span_assignments assigned + do_something_else + + dahdi_span_assignments remove + dahdi_span_assignments unassigned + do_something_completely_different + +.SH SEE ALSO +dahdi_span_assignments(8) + +.SH AUTHOR +dahdi_waitfor_span_assignments was written by Oron Peled. This manual +page was written by Tzafrir Cohen. Permission is granted to copy, +distribute and/or modify this document under the terms of the GNU +General Public License, Version 2 any later version published by the +Free Software Foundation. + diff --git a/doc/fxotune.8 b/doc/fxotune.8 new file mode 100644 index 0000000..d3257fc --- /dev/null +++ b/doc/fxotune.8 @@ -0,0 +1,208 @@ +.TH FXOTUNE "8" "9 June 2007" "asterisk" "System Manager's Manuals: Asterisk" +.SH NAME +fxotune \- automatically tune DAHDI FXO channels +.SH SYNOPSIS +.B fxotune \-i +.I [options] +\- detect mode + +.B fxotune \-d +.I [ options ] +\- dump mode + +.B fxotune \-s +.I [ options ] +\- Startup mode +.SH +.SH DESCRIPTION +.B fxotune +is a script that fine-tune parameters of the FXO modules of the +card. It has three modes of operation: + +.I Detect mode (\-i): +it detects and tunes all the available FXO channels. +It writes settings to a configuration file (/etc/fxotune.conf) +from which it can be loaded (e.g: at startup) using \-s . + +.I Dump mode (\-d): +Runs detection on a single DAHDI channel, and just dumps waveforms to +.B fxotune_dump.vals +is generated in the current directory. + +.I Startup mode (\-s): +fxotune just reads the settings from fxotune.conf into the FXO modules. + +You are advised to run fxotune on all FXO ports you have that support +it and that are connected. Note that the tunning is affected by e.g. +the physical parameters of the connection, and thus if it has been +radically changed, you may need to re-run fxotune. + +This program only works for the Digium TDM400P/800P/2400P cards and +compatible and the Xorcom Astribank devices. Other cards (notably X100P +cards and clones) do not have the hardware to support such tuning. + +The tuning process needs a clear line to do the tuning. In order to do +that, it runs in cycles of the following: sets the line off-hook, dials +a dial string (which should set the PSTN provider waiting for the next +digit), and then starts tuning. It has a limited ammount of time for +tuning before the PSTN gives up and gives a busy tone. So after a while +it hangs up and starts a new cycle. + +.B fxotune +has two operation modes: tune (\-i) and set (\-s). In the tune mode it +generates /etc/fxotune.conf, and in the set mode it merely applies the +parameters from fxotune.conf to device's ports. + +.SH OPTIONS +The following options below except \-v (verbose) affect only the +detection process and hence apply only to the +.I detect +and +.I dump +modes. + +In addition, to maintain compatibility with older versions of fxotune, +if in detect or dump mode there is a parameter with option before it, it +is considered to be the +.I dialstring +parameter (\-n). + +.B \-b +.I startdev +.RS +Start tuning from dahdi channel num. \fI startdev\fR: skip all previous +channels. By default starting from channel 1. + +In dump mode (\-d) this is the single channel that will be tested. +.RE + +.B \-e +.I stopdev +.RS +Tune only up to dahdi channel num. \fI stopdev\fR: skip all previous +channels. By default stopping at channel 252. + +In dump mode (\-d) this parameter is ignored. +.RE + +.B \-l +.I delay-to-silence +.RS +Time in seconds to wait after dialing the dial-string to get a clear line. +The default is 0. +before +.RE + +.B \-m +.I silence-good-for +.RS +Time in seconds which states how long the PSTN will wait after we dialed +the dial-string until it starts giving a busy tone. You can test this by +connecting an analog phone to the line and dialing. + +The default is 18 (18 seconds). +.RE + +.B \-n +.I dial-string +.RS +Digits to dial to the PSTN in order to get it stop its dialtone and +waiting for the next digit. + +The default is "4" (sending just the digit 4). It should work in most +cases. Again, this can be tested by connecting a phone to the PSTN line +and dialing the dial-string. +.RE + +.B \-t +.I detect-type +.RS +This option allows using the older detection method used by fxotune of +Zaptel 1.2. use +.B \-t 1 +for that older method. whereas +.B \-t 2 +(the default) uses the current method. + +This option only applies to detect mode (\-i). +.RE + +.B \-v[vvvv] +.RS +Sets debugging on. The more v-s, the higher debug level. + +Note that: \-vv \-v will actually set debug level to 1 instead of 3. +.RE + +.B \-w +.I wave-form +.RS +The default: \-1, for multitone waveform. Alternatively: a frequency of a +single tone. + +This option only applies to dump mode (\-d). +.RE + + +.SH EXAMPLES +.RS +fxotune \-i 9 +.RE +if you need to dial 9 for an external line. If you always get a line, you +can simply use any digit. +.RE + +.B \-s +.RS +Load settings from the last test. Used at startup. +.RE + +.SH FILES +.I /etc/fxotune.conf +.RS +The configuration file generated by fxotune in detect mode and from which +configuration is loaded when +.B \-s +is used. + +.SH NOTES +Running fxotune takes approximately a minute per port. If you wish to only +run fxotune for several ports, you can use the options \-b and \-e to set a +specific range of ports. Another useful trick is to actually keep asterisk +running, and only "destroy" the dahdi channels you wish to tune (dahdi +destroy channel NNN): other channels will be used by Asterisk, and hence +skipped. This can be useful if you have many FXO ports that are not connected. + +.B fxotune +writes immediately to +.B /etc/fxotune.conf +so if you stop it half-way, you may get a half-configured system. If you +have already tuned your FXO channels and wish to test-run fxotune again, +you are advised to backup /etc/fxotune.conf . + +The default for \-m is 18 seconds. This asusmes that you get a clear line +for at least 18 seconds. It is advised that you test that timeout earlier +by connecting a phone to the FXO line, dialing 4 (or whatever dial string +you put with \-n) and see how much time of silence you have. + +If you connect your device to a PSTN provider that is not in the US, there +is a similar operation you should apply before even getting to fxotune: +setting the opermode. The opermode sets a number of country-specific +parameters. For the Digium analog cards this is set through the kernel module +parameter 'opermode' . For the Xorcom Astribank this is set through the +variable 'opermode' in /etc/dahdi/xpp.conf . +For valid values of this parameter, see +/usr/share/asterisk/init_fxo_modes (FIXME: this has changed and will +change. Tzafrir). + +.SH SEE ALSO +dahdi_cfg(8), dahdi_tool(8), dahdi_monitor(8), asterisk(8). + +.SH AUTHOR +This manual page was written by Tzafrir Cohen +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common\-licenses/GPL. diff --git a/doc/fxstest.8 b/doc/fxstest.8 new file mode 100644 index 0000000..159480f --- /dev/null +++ b/doc/fxstest.8 @@ -0,0 +1,60 @@ +.TH "FXSTEST" "8" "9 June 2007" "asterisk" "System Manager's Manuals: Asterisk" + +.SH NAME +fxstest \- Simple tests for DAHDI FXS adapters +.SH SYNOPSIS + +.B fxstest /dev/dahdi/\fIN comand\fR + +.SH DESCRIPTION +fxstest can be used to issue one of a number simple tests to FXS +adapters (analog adapters intended to connect phones). + +.SH OPTIONS +All of those tests operate on a single dahdi channel which has to be an +FXS port, and must not be in use by Asterisk or any other program. + +The command has two mandatory parameters. +The first parameter is the device file to operate on. It is typically +/dev/dahdi/NN , a device file under /dev/dahdi . + +The second parameter is the name of the command to run on that channel: + +.I stats +.RS +Reports voltages +.RE + +.I regdump +.RS +Dumps ProSLIC registers +.RE + +.I tones +.RS +Plays a series of tones +.RE + +.I polarity +.RS +Requests channel to reverse polarity. +.RE + +.I ring +.RS +Rings phone +.RE + +.SH "SEE ALSO" +.PP +dahdi_tool(8), dahdi_cfg(8), dahdi_monitor(8), asterisk(8). +.SH BUGS +Does not allow testing channels beyond 249. Should support opening +channels through /dev/dahdi/channel . +.SH AUTHOR +.PP +This manual page was written by Tzafrir Cohen . +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. +.PP diff --git a/doc/patgen.8 b/doc/patgen.8 new file mode 100644 index 0000000..3585cff --- /dev/null +++ b/doc/patgen.8 @@ -0,0 +1,44 @@ +.TH patgen 8 "2 Dec 2009" +.SH NAME +patgen \(em Generates a Pattern for a DAHDI Clear Channel Test +.SH SYNOPSIS +.B patgen +.I dahdi-device + +.SH DESCRIPTION +.B patgen +Sends test data to a DAHDI channel. The channel should be of CLEAR +signalling (e.g: B channel of a PRI line). pattest(8) is used to test +the data at the other side. See its manual for more information. + +.B patgen +Must be able to write to the channel. Hence this cannot be used for a +channel used by Asterisk. + +.SH OPTIONS +.I dahdi-device +.RS +A DAHDI device. Can be either a device number or an explicit device file +name +.RE + +.SH EXAMPLE + patgen /dev/dahdi/5 + + patgen 305 + +.SH BUGS +Waiting for you to report them at . + +.SH SEE ALSO +pattest(8), dahdi_cfg(8), asterisk(8). + +.SH AUTHOR + +This manual page was written by Tzafrir Cohen +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common\-licenses/GPL. diff --git a/doc/pattest.8 b/doc/pattest.8 new file mode 100644 index 0000000..bce3f1c --- /dev/null +++ b/doc/pattest.8 @@ -0,0 +1,49 @@ +.TH pattest 8 "2 Dec 2009" +.SH NAME +pattest \(em Tests a Pattern for a DAHDI Clear Channel Test +.SH SYNOPSIS +.B pattest +.I dahdi-device + +.SH DESCRIPTION +.B pattest +Receives test data from a DAHDI channel and checks if it matches the +test pattern. The channel should be of CLEAR signalling (e.g: B channel +of a PRI line). patgen(8) is used to generate the data at the other side. + +.B pattest +Must be able to read from the channel. Hence this cannot be used for a +channel used by Asterisk. + +The pattern is a simple series of values from 0 to 255. Hence it takes +at most one sample to get in sync with the other side. If there is no +output, all is well. Output is an error message. + +.SH OPTIONS +.I dahdi-device +.RS +A DAHDI device. Can be either a device number or an explicit device file +name +.RE + +.SH EXAMPLE + pattest /dev/dahdi/5 + + pattest 305 +.RE + +.SH BUGS +Gives way too many errors when does not get any input. + +.SH SEE ALSO +patgen(8), dahdi_cfg(8), asterisk(8). + +.SH AUTHOR + +This manual page was written by Tzafrir Cohen +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common\-licenses/GPL. diff --git a/fxotune.c b/fxotune.c new file mode 100644 index 0000000..865dc70 --- /dev/null +++ b/fxotune.c @@ -0,0 +1,1328 @@ +/* + * fxotune.c -- A utility for tuning the various settings on the fxo + * modules for the TDM400 cards. + * + * by Matthew Fredrickson + * + * (C) 2004-2008 Digium, Inc. + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "dahdi_tools_version.h" +#include "fxotune.h" + +#define TEST_DURATION 2000 +#define BUFFER_LENGTH (2 * TEST_DURATION) +#define SKIP_SAMPLES 800 +#define SINE_SAMPLES 8000 + +static float sintable[SINE_SAMPLES]; + +static const float amplitude = 16384.0; + +static char *configfile = "/etc/fxotune.conf"; + +static int audio_dump_fd = -1; + +static int printbest = 0; + +#define MAX_RESULTS (5) +struct result_catalog { + int idx; + float echo; + float freqres; + struct wctdm_echo_coefs settings; +}; + +struct { + struct result_catalog results[MAX_RESULTS]; + int numactive; +} topresults; + +static char *usage = +"Usage: fxotune [-v[vv] (-s | -i | -d )\n" +"\n" +" -s : set previously calibrated echo settings\n" +" -i : calibrate echo settings\n" +" options : [] [-t ]\n" +" [-b ][-e ]\n" +" [-n ][-l ][-m ]\n" +" -d : dump input and output waveforms to ./fxotune_dump.vals\n" +" options : [-b ][-w ]\n" +" [-n ][-l ][-m ]\n" +" -v : more output (-vv, -vvv also)\n" +" -p : print the 5 best candidates for acim and coefficients settings\n" +" -x : Perform sin/cos functions using table lookup\n" +" -o : Write the received raw 16-bit signed linear audio that is\n" +" used in processing to the file specified by \n" +" -c \n" +"\n" +" - type of calibration\n" +" (default 2, old method 1)\n" +" \n" +" - defines a range of devices to test\n" +" (default: 1-252)\n" +" - string to dial to clear the line\n" +" (default 5)\n" +" - seconds to wait for line to clear (default 0)\n" +" - seconds before line will no longer be clear\n" +" (default 18)\n" +" - the device to perform waveform dump on\n" +" (default 1)\n" +" - -1 for multitone waveform, or frequency of\n" +" single tone (default -1)\n" +" - Alternative file to set from / calibrate to.\n" +" (Default: /etc/fxotune.conf)\n" +; + + +#define OUT_OF_BOUNDS(x) ((x) < 0 || (x) > 255) + +struct silence_info{ + char *dialstr; + /** fd of device we are working with */ + int device; + /** seconds we should wait after dialing the dialstring before we know for sure we'll have silence */ + int initial_delay; + /** seconds after which a reset should occur */ + int reset_after; + /** time of last reset */ + struct timeval last_reset; +}; + +static short outbuf[TEST_DURATION]; +static int debug = 0; + +static FILE *debugoutfile = NULL; + +static int use_table = 0; + +static int fxotune_read(int fd, void *buffer, int len) +{ + int res; + + res = read(fd, buffer, len); + + if ((res > 0) && (audio_dump_fd != -1)) { + res = write(audio_dump_fd, buffer, len); + } + + return res; +} + +/** + * Makes sure that the line is clear. + * Right now, we do this by relying on the user to specify how long after dialing the + * dialstring we can rely on the line being silent (before the telco complains about + * the user not hitting the next digit). + * + * A more robust way to do this would be to actually measure the sound levels on the line, + * but that's a lot more complicated, and this should work. + * + * @return 0 if succesful (no errors), 1 if unsuccesful + */ +static int ensure_silence(struct silence_info *info) +{ + struct timeval tv; + long int elapsedms; + int x = DAHDI_ONHOOK; + struct dahdi_dialoperation dop; + + gettimeofday(&tv, NULL); + + if (info->last_reset.tv_sec == 0) { + /* this is the first request, we will force it to run */ + elapsedms = -1; + } else { + /* this is not the first request, we will compute elapsed time */ + elapsedms = ((tv.tv_sec - info->last_reset.tv_sec) * 1000L + (tv.tv_usec - info->last_reset.tv_usec) / 1000L); + } + if (debug > 4) { + fprintf(stdout, "Reset line request received - elapsed ms = %li / reset after = %ld\n", elapsedms, info->reset_after * 1000L); + } + + if (elapsedms > 0 && elapsedms < info->reset_after * 1000L) + return 0; + + if (debug > 1){ + fprintf(stdout, "Resetting line\n"); + } + + /* do a line reset */ + /* prepare line for silence */ + /* Do line hookstate reset */ + + if (ioctl(info->device, DAHDI_HOOK, &x)) { + fprintf(stderr, "Unable to hang up fd %d\n", info->device); + return -1; + } + + sleep(2); + x = DAHDI_OFFHOOK; + if (ioctl(info->device, DAHDI_HOOK, &x)) { + fprintf(stderr, "Cannot bring fd %d off hook\n", info->device); + return -1; + } + sleep(2); /* Added to ensure that dial can actually takes place */ + + memset(&dop, 0, sizeof(dop)); + dop.op = DAHDI_DIAL_OP_REPLACE; + dop.dialstr[0] = 'T'; + dahdi_copy_string(dop.dialstr + 1, info->dialstr, sizeof(dop.dialstr)); + + + if (ioctl(info->device, DAHDI_DIAL, &dop)) { + fprintf(stderr, "Unable to dial!\n"); + return -1; + } + sleep(1); + sleep(info->initial_delay); + + + gettimeofday(&info->last_reset, NULL); + + + return 0; +} + +/** + * Generates a tone of specified frequency. + * + * @param hz the frequency of the tone to be generated + * @param idx the current sample + * to begenerated. For a normal waveform you need to increment + * this every time you execute the function. + * + * @return 16bit slinear sample for the specified index + */ +static short inline gentone(int hz, int idx) +{ + return amplitude * sin((idx * 2.0 * M_PI * hz)/8000); +} + +/* Using DTMF tones for now since they provide good mid band testing + * while not being harmonics of each other */ +static int freqs[] = {697, 770, 941, 1209, 1336, 1633}; +static int freqcount = 6; + +/** + * Generates a waveform of several frequencies. + * + * @param idx the current sample + * to begenerated. For a normal waveform you need to increment + * this every time you execute the function. + * + * @return 16bit slinear sample for the specified index + */ +static short inline genwaveform(int idx) +{ + int i = 0; + float response = (float)0; + for (i = 0; i < freqcount; i++){ + response += sin((idx * 2.0 * M_PI * freqs[i])/8000); + } + + + return amplitude * response / freqcount; +} + + +/** + * Calculates the RMS of the waveform buffer of samples in 16bit slinear format. + * prebuf the buffer of either shorts or floats + * bufsize the number of elements in the prebuf buffer (not the number of bytes!) + * short_format 1 if prebuf points to an array of shorts, 0 if it points to an array of floats + * + * Formula for RMS (http://en.wikipedia.org/wiki/Root_mean_square): + * + * Xrms = sqrt(1/N Sum(x1^2, x2^2, ..., xn^2)) + * + * Note: this isn't really a power calculation - but it gives a good measure of the level of the response + * + * @param prebuf the buffer containing the values to compute + * @param bufsize the size of the buffer + * @param short_format 1 if prebuf contains short values, 0 if it contains float values + */ +static float power_of(void *prebuf, int bufsize, int short_format) +{ + float sum_of_squares = 0; + int numsamples = 0; + float finalanswer = 0; + short *sbuf = (short*)prebuf; + float *fbuf = (float*)prebuf; + int i = 0; + + if (short_format) { + /* idiot proof checks */ + if (bufsize <= 0) + return -1; + + numsamples = bufsize; /* Got rid of divide by 2 - the bufsize parameter should give the number of samples (that's what it does for the float computation, and it should do it here as well) */ + + for (i = 0; i < numsamples; i++) { + sum_of_squares += ((float)sbuf[i] * (float)sbuf[i]); + } + } else { + /* Version for float inputs */ + for (i = 0; i < bufsize; i++) { + sum_of_squares += (fbuf[i] * fbuf[i]); + } + } + + finalanswer = sum_of_squares/(float)bufsize; /* need to divide by the number of elements in the sample for RMS calc */ + + if (finalanswer < 0) { + fprintf(stderr, "Error: Final answer negative number %f\n", finalanswer); + return -3; + } + + return sqrtf(finalanswer); +} + +/* + * In an effort to eliminate as much as possible the effect of outside noise, we use principles + * from the Fourier Transform to attempt to calculate the return loss of our signal for each setting. + * + * To begin, we send our output signal out on the line. We then receive back the reflected + * response. In the Fourier Transform, each evenly distributed frequency within the window + * is correlated (multiplied against, then the resulting samples are added together) with + * the real (cos) and imaginary (sin) portions of that frequency base to detect that frequency. + * + * Instead of doing a complete Fourier Transform, we solve the transform for only our signal + * by multiplying the received signal by the real and imaginary portions of our reference + * signal. This then gives us the real and imaginary values that we can use to calculate + * the return loss of the sinusoids that we sent out on the line. This is done by finding + * the magnitude (think polar form) of the vector resulting from the real and imaginary + * portions calculated above. + * + * This essentially filters out any other noise which maybe present on the line which is outside + * the frequencies used in our test multi-tone. + */ + +void init_sinetable(void) +{ + int i; + if (debug) { + fprintf(stdout, "Using sine tables with %d samples\n", SINE_SAMPLES); + } + for (i = 0; i < SINE_SAMPLES; i++) { + sintable[i] = sin(((float)i * 2.0 * M_PI )/(float)(SINE_SAMPLES)); + } +} + +/* Sine and cosine table lookup to use periodicity of the calculations being done */ +float sin_tbl(int arg, int num_per_period) +{ + arg = arg % num_per_period; + + arg = (arg * SINE_SAMPLES)/num_per_period; + + return sintable[arg]; +} + +float cos_tbl(int arg, int num_per_period) +{ + arg = arg % num_per_period; + + arg = (arg * SINE_SAMPLES)/num_per_period; + + arg = (arg + SINE_SAMPLES/4) % SINE_SAMPLES; /* Pi/2 adjustment */ + + return sintable[arg]; +} + + +static float db_loss(float measured, float reference) +{ + return 20 * (logf(measured/reference)/logf(10)); +} + +static void one_point_dft(const short *inbuf, int len, int frequency, float *real, float *imaginary) +{ + float myreal = 0, myimag = 0; + int i; + + for (i = 0; i < len; i++) { + if (use_table) { + myreal += (float) inbuf[i] * cos_tbl(i*frequency, 8000); + myimag += (float) inbuf[i] * sin_tbl(i*frequency, 8000); + } else { + myreal += (float) inbuf[i] * cos((i * 2.0 * M_PI * frequency)/8000); + myimag += (float) inbuf[i] * sin((i * 2.0 * M_PI * frequency)/8000); + } + } + + myimag *= -1; + + *real = myreal / (float) len; + *imaginary = myimag / (float) len; +} + + +static float calc_magnitude(short *inbuf, int insamps) +{ + float real, imaginary, magnitude; + float totalmagnitude = 0; + int i; + + for (i = 0; i < freqcount; i++) { + one_point_dft(inbuf, insamps, freqs[i], &real, &imaginary); + magnitude = sqrtf((real * real) + (imaginary * imaginary)); + totalmagnitude += magnitude; + } + + return totalmagnitude; +} + + +/** + * dumps input and output buffer contents for the echo test - used to see exactly what's going on + */ +static int maptone(int whichdahdi, int freq, char *dialstr, int delayuntilsilence) +{ + int i = 0; + int res = 0, x = 0; + struct dahdi_bufferinfo bi; + short inbuf[TEST_DURATION]; /* changed from BUFFER_LENGTH - this buffer is for short values, so it should be allocated using the length of the test */ + FILE *outfile = NULL; + int leadin = 50; + int trailout = 100; + struct silence_info sinfo; + float power_result; + float power_waveform; + float echo; + + outfile = fopen("fxotune_dump.vals", "w"); + if (!outfile) { + fprintf(stdout, "Cannot create fxotune_dump.vals\n"); + return -1; + } + + x = 1; + if (ioctl(whichdahdi, DAHDI_SETLINEAR, &x)) { + fprintf(stderr, "Unable to set channel to signed linear mode.\n"); + return -1; + } + + memset(&bi, 0, sizeof(bi)); + if (ioctl(whichdahdi, DAHDI_GET_BUFINFO, &bi)) { + fprintf(stderr, "Unable to get buffer information!\n"); + return -1; + } + bi.numbufs = 2; + bi.bufsize = TEST_DURATION; /* KD - changed from BUFFER_LENGTH; */ + bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; + bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; + if (ioctl(whichdahdi, DAHDI_SET_BUFINFO, &bi)) { + fprintf(stderr, "Unable to set buffer information!\n"); + return -1; + } + + /* Fill the output buffers */ + for (i = 0; i < leadin; i++) + outbuf[i] = 0; + for (; i < TEST_DURATION - trailout; i++){ + outbuf[i] = freq > 0 ? gentone(freq, i) : genwaveform(i); /* if frequency is negative, use a multi-part waveform instead of a single frequency */ + } + for (; i < TEST_DURATION; i++) + outbuf[i] = 0; + + /* Make sure the line is clear */ + memset(&sinfo, 0, sizeof(sinfo)); + sinfo.device = whichdahdi; + sinfo.dialstr = dialstr; + sinfo.initial_delay = delayuntilsilence; + sinfo.reset_after = 4; /* doesn't matter - we are only running one test */ + + if (ensure_silence(&sinfo)){ + fprintf(stderr, "Unable to get a clear outside line\n"); + return -1; + } + + /* Flush buffers */ + x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE | DAHDI_FLUSH_EVENT; + if (ioctl(whichdahdi, DAHDI_FLUSH, &x)) { + fprintf(stderr, "Unable to flush I/O: %s\n", strerror(errno)); + return -1; + } + + /* send data out on line */ + res = write(whichdahdi, outbuf, BUFFER_LENGTH); /* we are sending a TEST_DURATION length array of shorts (which are 2 bytes each) */ + if (res != BUFFER_LENGTH) { + fprintf(stderr, "Could not write all data to line\n"); + return -1; + } + +retry: + /* read return response */ + res = fxotune_read(whichdahdi, inbuf, BUFFER_LENGTH); + if (res != BUFFER_LENGTH) { + int dummy; + + ioctl(whichdahdi, DAHDI_GETEVENT, &dummy); + goto retry; + } + + /* write content of output buffer to debug file */ + power_result = power_of(inbuf, TEST_DURATION, 1); + power_waveform = power_of(outbuf, TEST_DURATION, 1); + echo = power_result/power_waveform; + + fprintf(outfile, "Buffers, freq=%d, outpower=%0.0f, echo=%0.4f\n", freq, power_result, echo); + fprintf(outfile, "Sample, Input (received from the line), Output (sent to the line)\n"); + for (i = 0; i < TEST_DURATION; i++){ + fprintf(outfile, "%d, %d, %d\n", + i, + inbuf[i], + outbuf[i] + ); + } + + fclose(outfile); + + fprintf(stdout, "echo ratio = %0.4f (%0.1f / %0.1f)\n", echo, power_result, power_waveform); + + return 0; +} + + +/** + * Initialize the data store for storing off best calculated results + */ +static void init_topresults(void) +{ + topresults.numactive = 0; +} + + +/** + * If this is a best result candidate, store in the top results data store + * This is dependent on being the lowest echo value + * + * @param tbleoffset - The offset into the echo_trys table used + * @param setting - Pointer to the settings used to achieve the fgiven value + * @param echo - The calculated echo return value (in dB) + * @param echo - The calculated magnitude of the response + */ +static void set_topresults(int tbloffset, struct wctdm_echo_coefs *setting, float echo, float freqres) +{ + int place; + int idx; + + for ( place = 0; place < MAX_RESULTS && place < topresults.numactive; place++) { + if (echo < topresults.results[place].echo) { + break; + } + } + + if (place < MAX_RESULTS) { + /* move results to the bottom */ + for (idx = topresults.numactive-2; idx >= place; idx--) { + topresults.results[idx+1] = topresults.results[idx]; + } + topresults.results[place].idx = tbloffset; + topresults.results[place].settings = *setting; + topresults.results[place].echo = echo; + topresults.results[place].freqres = freqres; + if (MAX_RESULTS > topresults.numactive) { + topresults.numactive++; + } + } +} + + +/** + * Prints the top results stored to stdout + * + * @param header - Text that goes in the header of the response + */ +static void print_topresults(char * header) +{ + int item; + + fprintf(stdout, "Top %d results for %s\n", topresults.numactive, header); + for (item = 0; item < topresults.numactive; item++) { + fprintf(stdout, "Res #%d: index=%d, %3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d: magnitude = %0.0f, echo = %0.4f dB\n", + item+1, topresults.results[item].idx, topresults.results[item].settings.acim, + topresults.results[item].settings.coef1, topresults.results[item].settings.coef2, + topresults.results[item].settings.coef3, topresults.results[item].settings.coef4, + topresults.results[item].settings.coef5, topresults.results[item].settings.coef6, + topresults.results[item].settings.coef7, topresults.results[item].settings.coef8, + topresults.results[item].freqres, topresults.results[item].echo); + + } +} + + +/** + * Perform calibration type 2 on the specified device + * + * Determine optimum echo coefficients for the specified device + * + * New tuning strategy. If we have a number that we can dial that will result in silence from the + * switch, the tune will be *much* faster (we don't have to keep hanging up and dialing a digit, etc...) + * The downside is that the user needs to actually find a 'no tone' phone number at their CO's switch - but for + * really fixing echo problems, this is what it takes. + * + * Also, for the purposes of optimizing settings, if we pick a single frequency and test with that, + * we can try a whole bunch of impedence/echo coefficients. This should give better results than trying + * a bunch of frequencies, and we can always do a a frequency sweep to pick between the best 3 or 4 + * impedence/coefficients configurations. + * + * Note: It may be possible to take this even further and do some pertubation analysis on the echo coefficients + * themselves (maybe use the 72 entry sweep to find some settings that are close to working well, then + * deviate the coefficients a bit to see if we can improve things). A better way to do this would be to + * use the optimization strategy from silabs. For reference, here is an application note that describes + * the echo coefficients (and acim values): + * + * http://www.silabs.com/Support%20Documents/TechnicalDocs/an84.pdf + * + * See Table 13 in this document for a breakdown of acim values by region. + * + * http://www.silabs.com/Support%20Documents/TechnicalDocs/si3050-18-19.pdf + * + */ +static int acim_tune2(int whichdahdi, int freq, char *dialstr, int delayuntilsilence, int silencegoodfor, struct wctdm_echo_coefs *coefs_out) +{ + int i = 0; + int res = 0, x = 0; + int lowesttry = -1; + float lowesttryresult = 999999999999.0; + float lowestecho = 999999999999.0; + struct dahdi_bufferinfo bi; + short inbuf[TEST_DURATION * 2]; + struct silence_info sinfo; + int echo_trys_size = 72; + int trys = 0; + float waveform_power; + float freq_result; + float echo; + + init_topresults(); + + if (debug && !debugoutfile) { + if (!(debugoutfile = fopen("fxotune.vals", "w"))) { + fprintf(stdout, "Cannot create fxotune.vals\n"); + return -1; + } + } + + /* Set echo settings */ + if (ioctl(whichdahdi, WCTDM_SET_ECHOTUNE, &echo_trys[0])) { + fprintf(stderr, "Unable to set impedance on fd %d\n", whichdahdi); + return -1; + } + + x = 1; + if (ioctl(whichdahdi, DAHDI_SETLINEAR, &x)) { + fprintf(stderr, "Unable to set channel to signed linear mode.\n"); + return -1; + } + + memset(&bi, 0, sizeof(bi)); + if (ioctl(whichdahdi, DAHDI_GET_BUFINFO, &bi)) { + fprintf(stderr, "Unable to get buffer information!\n"); + return -1; + } + bi.numbufs = 2; + bi.bufsize = BUFFER_LENGTH; + bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; + bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; + if (ioctl(whichdahdi, DAHDI_SET_BUFINFO, &bi)) { + fprintf(stderr, "Unable to set buffer information!\n"); + return -1; + } + x = DAHDI_OFFHOOK; + if (ioctl(whichdahdi, DAHDI_HOOK, &x)) { + fprintf(stderr, "Cannot bring fd %d off hook", whichdahdi); + return -1; + } + + + /* Set up silence settings */ + memset(&sinfo, 0, sizeof(sinfo)); + sinfo.device = whichdahdi; + sinfo.dialstr = dialstr; + sinfo.initial_delay = delayuntilsilence; + sinfo.reset_after = silencegoodfor; + + /* Fill the output buffers */ + for (i = 0; i < TEST_DURATION; i++) + outbuf[i] = freq > 0 ? gentone(freq, i) : genwaveform(i); /* if freq is negative, use a multi-frequency waveform */ + + /* compute power of input (so we can later compute echo levels relative to input) */ + waveform_power = calc_magnitude(outbuf, TEST_DURATION); + + /* sweep through the various coefficient settings and see how our responses look */ + + for (trys = 0; trys < echo_trys_size; trys++){ + + /* ensure silence on the line */ + if (ensure_silence(&sinfo)){ + fprintf(stderr, "Unable to get a clear outside line\n"); + return -1; + } + + if (ioctl(whichdahdi, WCTDM_SET_ECHOTUNE, &echo_trys[trys])) { + fprintf(stderr, "Unable to set echo coefficients on fd %d\n", whichdahdi); + return -1; + } + + /* Flush buffers */ + x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE | DAHDI_FLUSH_EVENT; + if (ioctl(whichdahdi, DAHDI_FLUSH, &x)) { + fprintf(stderr, "Unable to flush I/O: %s\n", strerror(errno)); + return -1; + } + + /* send data out on line */ + res = write(whichdahdi, outbuf, BUFFER_LENGTH); + if (res != BUFFER_LENGTH) { + fprintf(stderr, "Could not write all data to line\n"); + return -1; + } + +retry: + /* read return response */ + res = fxotune_read(whichdahdi, inbuf, BUFFER_LENGTH * 2); + if (res != BUFFER_LENGTH * 2) { + int dummy; + + ioctl(whichdahdi, DAHDI_GETEVENT, &dummy); + goto retry; + } + + freq_result = calc_magnitude(inbuf, TEST_DURATION * 2); + echo = db_loss(freq_result, waveform_power); + +#if 0 + if (debug > 0) + fprintf(stdout, "%3d,%d,%d,%d,%d,%d,%d,%d,%d: magnitude = %0.0f, echo = %0.4f dB\n", + echo_trys[trys].acim, echo_trys[trys].coef1, echo_trys[trys].coef2, + echo_trys[trys].coef3, echo_trys[trys].coef4, echo_trys[trys].coef5, + echo_trys[trys].coef6, echo_trys[trys].coef7, echo_trys[trys].coef8, + freq_result, echo); +#endif + + if (freq_result < lowesttryresult){ + lowesttry = trys; + lowesttryresult = freq_result; + lowestecho = echo; + } + if (debug) { + char result[256]; + snprintf(result, sizeof(result), "%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%f,%f", + echo_trys[trys].acim, + echo_trys[trys].coef1, + echo_trys[trys].coef2, + echo_trys[trys].coef3, + echo_trys[trys].coef4, + echo_trys[trys].coef5, + echo_trys[trys].coef6, + echo_trys[trys].coef7, + echo_trys[trys].coef8, + freq_result, + echo + ); + + fprintf(debugoutfile, "%s\n", result); + fprintf(stdout, "%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d: magnitude = %0.0f, echo = %0.4f dB\n", + echo_trys[trys].acim, echo_trys[trys].coef1, echo_trys[trys].coef2, + echo_trys[trys].coef3, echo_trys[trys].coef4, echo_trys[trys].coef5, + echo_trys[trys].coef6, echo_trys[trys].coef7, echo_trys[trys].coef8, + freq_result, echo); + } + + if (printbest) { + set_topresults(trys, &echo_trys[trys], echo, freq_result); + } + } + + if (debug > 0) + fprintf(stdout, "Config with lowest response = %d, magnitude = %0.0f, echo = %0.4f dB\n", lowesttry, lowesttryresult, lowestecho); + + memcpy(coefs_out, &echo_trys[lowesttry], sizeof(struct wctdm_echo_coefs)); + if (printbest) { + print_topresults("Acim2_tune Test"); + } + + return 0; +} + +/** + * Perform calibration type 1 on the specified device. Only tunes the line impedance. Look for best response range + */ +static int acim_tune(int whichdahdi, char *dialstr, int delayuntilsilence, int silencegoodfor, struct wctdm_echo_coefs *coefs_out) +{ + int i = 0, freq = 0, acim = 0; + int res = 0, x = 0; + struct dahdi_bufferinfo bi; + struct wctdm_echo_coefs coefs; + short inbuf[TEST_DURATION]; /* changed from BUFFER_LENGTH - this buffer is for short values, so it should be allocated using the length of the test */ + int lowest = 0; + FILE *outfile = NULL; + float acim_results[16]; + struct silence_info sinfo; + + if (debug) { + outfile = fopen("fxotune.vals", "w"); + if (!outfile) { + fprintf(stdout, "Cannot create fxotune.vals\n"); + return -1; + } + } + + /* Set up silence settings */ + memset(&sinfo, 0, sizeof(sinfo)); + sinfo.device = whichdahdi; + sinfo.dialstr = dialstr; + sinfo.initial_delay = delayuntilsilence; + sinfo.reset_after = silencegoodfor; + + /* Set echo settings */ + memset(&coefs, 0, sizeof(coefs)); + if (ioctl(whichdahdi, WCTDM_SET_ECHOTUNE, &coefs)) { + fprintf(stdout, "Skipping non-TDM / non-FXO\n"); + return -1; + } + + x = 1; + if (ioctl(whichdahdi, DAHDI_SETLINEAR, &x)) { + fprintf(stderr, "Unable to set channel to signed linear mode.\n"); + return -1; + } + + memset(&bi, 0, sizeof(bi)); + if (ioctl(whichdahdi, DAHDI_GET_BUFINFO, &bi)) { + fprintf(stderr, "Unable to get buffer information!\n"); + return -1; + } + bi.numbufs = 2; + bi.bufsize = BUFFER_LENGTH; + bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; + bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; + if (ioctl(whichdahdi, DAHDI_SET_BUFINFO, &bi)) { + fprintf(stderr, "Unable to set buffer information!\n"); + return -1; + } + + for (acim = 0; acim < 16; acim++) { + float freq_results[15]; + + coefs.acim = acim; + if (ioctl(whichdahdi, WCTDM_SET_ECHOTUNE, &coefs)) { + fprintf(stderr, "Unable to set impedance on fd %d\n", whichdahdi); + return -1; + } + + for (freq = 200; freq <=3000; freq+=200) { + /* Fill the output buffers */ + for (i = 0; i < TEST_DURATION; i++) + outbuf[i] = gentone(freq, i); + + /* Make sure line is ready for next test iteration */ + if (ensure_silence(&sinfo)){ + fprintf(stderr, "Unable to get a clear line\n"); + return -1; + } + + + /* Flush buffers */ + x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE | DAHDI_FLUSH_EVENT; + if (ioctl(whichdahdi, DAHDI_FLUSH, &x)) { + fprintf(stderr, "Unable to flush I/O: %s\n", strerror(errno)); + return -1; + } + + /* send data out on line */ + res = write(whichdahdi, outbuf, BUFFER_LENGTH); + if (res != BUFFER_LENGTH) { + fprintf(stderr, "Could not write all data to line\n"); + return -1; + } + + /* read return response */ +retry: + /* read return response */ + res = fxotune_read(whichdahdi, inbuf, BUFFER_LENGTH); + if (res != BUFFER_LENGTH) { + int dummy; + + ioctl(whichdahdi, DAHDI_GETEVENT, &dummy); + goto retry; + } + + /* calculate power of response */ + + freq_results[(freq/200)-1] = power_of(inbuf+SKIP_SAMPLES, TEST_DURATION-SKIP_SAMPLES, 1); /* changed from inbuf+SKIP_BYTES, BUFFER_LENGTH-SKIP_BYTES, 1 */ + if (debug) fprintf(outfile, "%d,%d,%f\n", acim, freq, freq_results[(freq/200)-1]); + } + acim_results[acim] = power_of(freq_results, 15, 0); + } + + if (debug) { + for (i = 0; i < 16; i++) + fprintf(outfile, "acim_results[%d] = %f\n", i, acim_results[i]); + } + /* Find out what the "best" impedance is for the line */ + lowest = 0; + for (i = 0; i < 16; i++) { + if (acim_results[i] < acim_results[lowest]) { + lowest = i; + } + } + + coefs_out->acim = lowest; + coefs_out->coef1 = 0; + coefs_out->coef2 = 0; + coefs_out->coef3 = 0; + coefs_out->coef4 = 0; + coefs_out->coef5 = 0; + coefs_out->coef6 = 0; + coefs_out->coef7 = 0; + coefs_out->coef8 = 0; + + return 0; +} + +static int channel_is_fxo(int channo) +{ + int res = 0; + int fd; + const char *CTL_DEV = "/dev/dahdi/ctl"; + struct dahdi_params params; + + fd = open(CTL_DEV, O_RDWR, 0600); + if (-1 == fd) { + fprintf(stderr, "Failed to open %s: %s\n", + CTL_DEV, strerror(errno)); + return -1; + } + params.channo = channo; + if (ioctl(fd, DAHDI_GET_PARAMS, ¶ms)) { + fprintf(stderr, + "%d is not a valid channel number.\n", channo); + res = -1; + } else if (0 == (__DAHDI_SIG_FXS & params.sigcap)) { + fprintf(stderr, + "Channel %d is not an FXO port.\n", channo); + res = -1; + } else if (0 == params.sigtype) { + fprintf(stderr, + "Cannot run on unconfigured channel %d. Please run dahdi_cfg to configure channels before running fxotune.\n", + channo); + res = -1; + } + close(fd); + return res; +} + +static int channel_open(int channo) +{ + int fd; + const char *DEVICE = "/dev/dahdi/channel"; + + if (channo > 0) { + if (channel_is_fxo(channo)) + return -1; + + fd = open(DEVICE, O_RDWR, 0600); + if (fd < 0) { + perror(DEVICE); + return -1; + } + + if (ioctl(fd, DAHDI_SPECIFY, &channo) < 0) { + perror("DADHI_SPECIFY ioctl failed"); + close(fd); + fd = -1; + } + } else { + fprintf(stderr, + "Specified channel is not a valid channel number"); + fd = -1; + } + return fd; +} + +/** + * Reads echo register settings from the configuration file and pushes them into + * the appropriate devices + * + * @param configfilename the path of the file that the calibration results should be written to + * + * @return 0 if successful, !0 otherwise + */ +static int do_set(char *configfilename, int dev_range, int startdev, int stopdev) +{ + FILE *fp = NULL; + int res = 0; + int fd = 0; + + fp = fopen(configfile, "r"); + + if (!fp) { + fprintf(stdout, "Cannot open %s!\n",configfile); + return -1; + } + + + while (res != EOF) { + struct wctdm_echo_coefs mycoefs; + char completedahdipath[56] = ""; + int mydahdi,myacim,mycoef1,mycoef2,mycoef3,mycoef4,mycoef5,mycoef6,mycoef7,mycoef8; + + + res = fscanf(fp, "%d=%d,%d,%d,%d,%d,%d,%d,%d,%d",&mydahdi,&myacim,&mycoef1, + &mycoef2,&mycoef3,&mycoef4,&mycoef5,&mycoef6,&mycoef7, + &mycoef8); + + if (res == EOF) { + break; + } + if (dev_range && (mydahdi < startdev || mydahdi > stopdev)) + continue; + + /* Check to be sure conversion is done correctly */ + if (OUT_OF_BOUNDS(myacim) || OUT_OF_BOUNDS(mycoef1)|| + OUT_OF_BOUNDS(mycoef2)|| OUT_OF_BOUNDS(mycoef3)|| + OUT_OF_BOUNDS(mycoef4)|| OUT_OF_BOUNDS(mycoef5)|| + OUT_OF_BOUNDS(mycoef6)|| OUT_OF_BOUNDS(mycoef7)|| OUT_OF_BOUNDS(mycoef8)) { + + fprintf(stdout, "Bounds check error on inputs from %s:%d\n", configfile, mydahdi); + return -1; + } + + mycoefs.acim = myacim; + mycoefs.coef1 = mycoef1; + mycoefs.coef2 = mycoef2; + mycoefs.coef3 = mycoef3; + mycoefs.coef4 = mycoef4; + mycoefs.coef5 = mycoef5; + mycoefs.coef6 = mycoef6; + mycoefs.coef7 = mycoef7; + mycoefs.coef8 = mycoef8; + + if (debug >= 2) + printf("fxotune: set channel %d\n", mydahdi); + fd = channel_open(mydahdi); + if (fd < 0) { + return -1; + } + + if (ioctl(fd, WCTDM_SET_ECHOTUNE, &mycoefs)) { + fprintf(stdout, "%s: %s\n", completedahdipath, strerror(errno)); + return -1; + } + + close(fd); + } + + fclose(fp); + + if (debug) + fprintf(stdout, "fxotune: successfully set echo coeffecients on FXO modules\n"); + return 0; +} + +/** + * Output waveform information from a single test + * + * Clears the line, then sends a single waveform (multi-tone, or single tone), and listens + * for the response on the line. Output is written to fxotune_dump.vals + * + * @param startdev the device to test + * @param dialstr the string that should be dialed to clear the dialtone from the line + * @param delayuntilsilence the number of seconds to wait after dialing dialstr before starting the test + * @param silencegoodfor the number of seconds that the test can run before having to reset the line again + * (this is basically the amount of time it takes before the 'if you'd like to make a call...' message + * kicks in after you dial dialstr. This test is so short that the value is pretty much ignored. + * @param waveformtype the type of waveform to use - -1 = multi-tone waveform, otherwise the specified value + * is used as the frequency of a single tone. A value of 0 will output silence. + */ +static int do_dump(int startdev, char* dialstr, int delayuntilsilence, int silencegoodfor, int waveformtype) +{ + int res = 0; + int fd; + char dahdidev[80] = ""; + + int dahdimodule = startdev; + fd = channel_open(dahdimodule); + if (fd < 0) { + return -1; + } + + fprintf(stdout, "Dumping module %s\n", dahdidev); + res = maptone(fd, waveformtype, dialstr, delayuntilsilence); + + close(fd); + + if (res) { + fprintf(stdout, "Failure!\n"); + return res; + } else { + fprintf(stdout, "Done!\n"); + return 0; + } + +} + +/** + * Performs calibration on all specified devices + * + * @param startdev the first device to check + * @param enddev the last device to check + * @param calibtype the type of calibration to perform. 1=old style (loops through individual frequencies + * doesn't optimize echo coefficients. 2=new style (uses multi-tone and optimizes echo coefficients + * and acim setting) + * @param configfilename the path of the file that the calibration results should be written to + * @param dialstr the string that should be dialed to clear the dialtone from the line + * @param delayuntilsilence the number of seconds to wait after dialing dialstr before starting the test + * @param silencegoodfor the number of seconds that the test can run before having to reset the line again + * (this is basically the amount of time it takes before the 'if you'd like to make a call...' message + * kicks in after you dial dialstr + * + * @return 0 if successful, -1 for serious error such as device not available , > 0 indicates the number of channels + */ +static int do_calibrate(int startdev, int enddev, int calibtype, char* configfilename, char* dialstr, int delayuntilsilence, int silencegoodfor) +{ + int problems = 0; + int res = 0; + int configfd, fd; + int devno = 0; + struct wctdm_echo_coefs coefs; + + configfd = open(configfile, O_CREAT|O_TRUNC|O_WRONLY, 0666); + + if (configfd < 0) { + fprintf(stderr, "Cannot generate config file %s: open: %s\n", configfile, strerror(errno)); + return -1; + } + + for (devno = startdev; devno <= enddev; devno++) { + fd = channel_open(devno); + if (fd < 0) { + continue; + } + + fprintf(stdout, "Tuning module %d\n", devno); + + if (1 == calibtype) + res = acim_tune(fd, dialstr, delayuntilsilence, silencegoodfor, &coefs); + else + res = acim_tune2(fd, -1, dialstr, delayuntilsilence, silencegoodfor, &coefs); + + close(fd); + + if (res) { + fprintf(stdout, "Failure!\n"); + problems++; + } else { + fprintf(stdout, "Done!\n"); + } + + if (res == 0) { + + /* Do output to file */ + int len = 0; + static char output[255] = ""; + + snprintf(output, sizeof(output), "%d=%d,%d,%d,%d,%d,%d,%d,%d,%d\n", + devno, + coefs.acim, + coefs.coef1, + coefs.coef2, + coefs.coef3, + coefs.coef4, + coefs.coef5, + coefs.coef6, + coefs.coef7, + coefs.coef8 + ); + + if (debug) + fprintf(stdout, "Found best echo coefficients: %s\n", output); + + len = strlen(output); + res = write(configfd, output, strlen(output)); + if (res != len) { + fprintf(stdout, "Unable to write line \"%s\" to file.\n", output); + return -1; + } + } + } + + close(configfd); + + if (problems) + fprintf(stdout, "Unable to tune %d devices, even though those devices are present\n", problems); + + return problems; +} + +int main(int argc , char **argv) +{ + int startdev = 1; /* -b */ + int stopdev = 252; /* -e */ + int dev_range = 0; /* false */ + int calibtype = 2; /* -t */ + int waveformtype = -1; /* -w multi-tone by default. If > 0, single tone of specified frequency */ + int delaytosilence = 0; /* -l */ + int silencegoodfor = 18; /* -m */ + char* dialstr = "5"; /* -n */ + int res = 0; + int doset = 0; /* -s */ + int docalibrate = 0; /* -i */ + int dodump = 0; /* -d */ + int i = 0; + int moreargs; + + for (i = 1; i < argc; i++){ + if (!(argv[i][0] == '-' || argv[i][0] == '/') || (strlen(argv[i]) <= 1)){ + fprintf(stdout, "Unknown option : %s\n", argv[i]); + /* Show usage */ + fputs(usage, stdout); + return -1; + } + + moreargs = (i < argc - 1); + + switch(argv[i][1]){ + case 's': + doset=1; + continue; + case 'i': + docalibrate = 1; + if (moreargs){ /* we need to check for a value after 'i' for backwards compatability with command line options of old fxotune */ + if (argv[i+1][0] != '-' && argv[i+1][0] != '/') + dialstr = argv[++i]; + } + continue; + case 'c': + configfile = moreargs ? argv[++i] : configfile; + continue; + case 'd': + dodump = 1; + continue; + case 'b': + startdev = moreargs ? atoi(argv[++i]) : startdev; + dev_range = 1; + break; + case 'e': + stopdev = moreargs ? atoi(argv[++i]) : stopdev; + dev_range = 1; + break; + case 't': + calibtype = moreargs ? atoi(argv[++i]) : calibtype; + break; + case 'w': + waveformtype = moreargs ? atoi(argv[++i]) : waveformtype; + break; + case 'l': + delaytosilence = moreargs ? atoi(argv[++i]) : delaytosilence; + break; + case 'm': + silencegoodfor = moreargs ? atoi(argv[++i]) : silencegoodfor; + break; + case 'n': + dialstr = moreargs ? argv[++i] : dialstr; + break; + case 'p': + printbest++; + break; + case 'x': + use_table = 1; + break; + case 'v': + debug = strlen(argv[i])-1; + break; + case 'o': + if (moreargs) { + audio_dump_fd = open(argv[++i], O_WRONLY|O_CREAT|O_TRUNC, 0666); + if (audio_dump_fd == -1) { + fprintf(stdout, "Unable to open file %s: %s\n", argv[i], strerror(errno)); + return -1; + } + break; + } else { + fprintf(stdout, "No path supplied to -o option!\n"); + return -1; + } + default: + fprintf(stdout, "Unknown option : %s\n", argv[i]); + /* Show usage */ + fputs(usage, stdout); + return -1; + + } + } + + if (debug > 3){ + fprintf(stdout, "Running with parameters:\n"); + fprintf(stdout, "\tdoset=%d\n", doset); + fprintf(stdout, "\tdocalibrate=%d\n", docalibrate); + fprintf(stdout, "\tdodump=%d\n", dodump); + fprintf(stdout, "\tprint best settings=%d\n", printbest); + fprintf(stdout, "\tstartdev=%d\n", startdev); + fprintf(stdout, "\tstopdev=%d\n", stopdev); + fprintf(stdout, "\tcalibtype=%d\n", calibtype); + fprintf(stdout, "\twaveformtype=%d\n", waveformtype); + fprintf(stdout, "\tdelaytosilence=%d\n", delaytosilence); + fprintf(stdout, "\tsilencegoodfor=%d\n", silencegoodfor); + fprintf(stdout, "\tdialstr=%s\n", dialstr); + fprintf(stdout, "\tdebug=%d\n", debug); + } + + if(use_table) { + init_sinetable(); + } + + if (docalibrate){ + res = do_calibrate(startdev, stopdev, calibtype, configfile, dialstr, delaytosilence, silencegoodfor); + if (!res) + return do_set(configfile, dev_range, startdev, stopdev); + else + return -1; + } + + if (doset) + return do_set(configfile, dev_range, startdev, stopdev); + + if (dodump){ + res = do_dump(startdev, dialstr, delaytosilence, silencegoodfor, waveformtype); + if (!res) + return 0; + else + return -1; + } + + fputs(usage, stdout); + return -1; +} diff --git a/fxotune.h b/fxotune.h new file mode 100644 index 0000000..97b02e6 --- /dev/null +++ b/fxotune.h @@ -0,0 +1,119 @@ +/* + * fxotune.h -- data structures and associated definitions for fxotune.c + * + * By Matthew Fredrickson + * + * Echo coefficients and acim register values taken from AN84 from Silicon + * Laboratories app note AN84 for setting echo cancellation coefficients + * + * (C) 2005 Digium, Inc. + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +struct wctdm_echo_coefs echo_trys [] = +{ + /* 600 ohm echo settings */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 10, 0, 6, 1, 254, 2, 255, 0, 0}, + { 3, 255, 255, 0, 1, 0, 0, 0, 0}, + { 3, 1, 253, 253, 2, 255, 0, 0, 0}, + { 9, 254, 251, 255, 2, 0, 1, 0, 0}, + { 5, 3, 251, 250, 2, 254, 0, 0, 255}, + { 8, 253, 2, 244, 255, 10, 244, 3, 253}, + { 10, 249, 244, 8, 12, 245, 252, 0, 1}, + + /* 900 ohm echo settings */ + { 1, 0, 0, 0, 0, 0, 0, 0, 0}, + { 10, 252, 255, 1, 255, 0, 0, 0, 0}, + { 7, 255, 251, 251, 2, 255, 255, 1, 255}, + { 3, 1, 251, 250, 1, 254, 255, 0, 255}, + { 5, 252, 250, 0, 0, 255, 1, 0, 0}, + { 5, 3, 251, 250, 1, 253, 0, 0, 255}, + { 8, 253, 2, 244, 255, 10, 244, 3, 253}, + { 10, 249, 244, 8, 12, 245, 252, 0, 1}, + + /* 270 ohm + (750 ohm || 150 nF) (CTR21) */ + { 2, 0, 0, 0, 0, 0, 0, 0, 0}, + { 7, 0, 0, 255, 254, 0, 0, 0, 0}, + { 9, 0, 253, 254, 2, 255, 0, 0, 0}, + { 5, 1, 249, 254, 4, 253, 1, 0, 0}, + { 5, 252, 250, 1, 1, 254, 0, 255, 0}, + { 5, 3, 251, 250, 2, 253, 255, 255, 255}, + { 8, 253, 2, 244, 255, 10, 244, 3, 253}, + { 10, 249, 244, 8, 12, 245, 252, 0, 1}, + + /* 220 ohm + (820 ohm || 120 nF) (Australia/NewZealand) and 220 ohm + (820 ohm + * || 115nF) (Slovakia/SAfrica/Germany/Austria/Bulgaria) + */ + { 3, 0, 0, 0, 0, 0, 0, 0, 0}, + { 7, 0, 255, 254, 255, 0, 255, 0, 0}, + { 9, 0, 253, 253, 1, 255, 0, 0, 0}, + { 5, 1, 249, 254, 3, 253, 1, 0, 0}, + { 5, 252, 250, 1, 1, 254, 0, 255, 0}, + { 5, 3, 251, 251, 2, 253, 255, 255, 255}, + { 8, 253, 2, 244, 255, 10, 244, 3, 253}, + { 10, 249, 244, 8, 12, 245, 252, 0, 1}, + + /* 370 ohm + (620ohm || 310nF) (New Zealand #2/India) CO Termination */ + { 4, 0, 0, 0, 0, 0, 0, 0, 0}, + { 9, 255, 1, 4, 0, 0, 1, 255, 0}, + { 9, 0, 253, 0, 3, 254, 0, 0, 255}, + { 9, 2, 250, 253, 5, 253, 1, 0 ,255}, + { 5, 252, 250, 1, 2, 255, 0 ,255, 0}, + { 5, 3, 251, 250, 3, 254, 255, 255, 255}, + { 8, 253, 2, 244, 255, 10, 244, 3, 253}, + { 10, 249, 244, 8, 12, 245, 252, 0, 1}, + + /* 320 ohm + (1050ohm || 230 nF) (England) CO Termination */ + { 5, 0, 0, 0, 0, 0, 0, 0, 0}, + { 9, 0 ,255, 1, 255, 255, 0, 255, 0}, + { 5, 255, 252, 0, 2, 254, 0, 255, 255}, + { 9, 2, 250, 253, 4, 252, 0, 255, 255}, + { 5, 252, 250, 1, 1, 254, 0 ,255, 255}, + { 5, 3, 251, 250, 2, 253, 255, 255, 254}, + { 3, 1, 1, 242, 2, 9, 245, 3, 253}, + { 10, 249, 244, 8, 12, 245, 252, 0, 1}, + + /* 370 ohm + (820 ohm || 110 nF) CO Termination */ + { 6, 0, 0, 0, 0, 0, 0, 0, 0}, + { 6, 1, 254, 253, 0, 255, 0, 0, 0}, + { 9, 0, 251, 252, 2, 255, 0, 0, 0}, + { 5, 1, 248, 252, 4, 253, 1, 0, 0}, + { 5, 252, 250, 0, 0, 254, 0 , 255, 0}, + { 5, 3, 251, 250, 2, 253, 255, 255, 254}, + { 3, 1, 1, 242, 2, 9, 245, 3, 253}, + { 10, 249, 244, 8, 12, 245, 252, 0, 1}, + + /* 275 ohm + (780 ohm || 115 nF) CO Termination */ + { 7, 0, 0, 0, 0, 0, 0, 0, 0}, + { 7, 255, 255, 255, 255, 0, 0, 0, 0}, + { 9, 0, 253, 254, 2, 255, 0, 0, 0}, + { 5, 1, 249, 254, 4, 253, 1, 0, 0}, + { 5, 252, 250, 1, 1, 254, 0, 255, 0}, + { 5, 3, 251, 250, 2, 253, 255, 255, 255}, + { 8, 253, 2, 244, 255, 10, 244, 3, 253}, + { 10, 249, 244, 8, 12, 245, 252, 0, 1}, + + /* Make sure we include the rest of the impedances */ + { 8, 0, 0, 0, 0, 0, 0, 0, 0}, + { 9, 0, 0, 0, 0, 0, 0, 0, 0}, + { 10, 0, 0, 0, 0, 0, 0, 0, 0}, + { 11, 0, 0, 0, 0, 0, 0, 0, 0}, + { 12, 0, 0, 0, 0, 0, 0, 0, 0}, + { 13, 0, 0, 0, 0, 0, 0, 0, 0}, + { 14, 0, 0, 0, 0, 0, 0, 0, 0}, + { 15, 0, 0, 0, 0, 0, 0, 0, 0}, +}; + diff --git a/fxstest.c b/fxstest.c new file mode 100644 index 0000000..94709c6 --- /dev/null +++ b/fxstest.c @@ -0,0 +1,373 @@ +/* + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tonezone.h" +#include "dahdi_tools_version.h" + +static int tones[] = { + DAHDI_TONE_DIALTONE, + DAHDI_TONE_BUSY, + DAHDI_TONE_RINGTONE, + DAHDI_TONE_CONGESTION, + DAHDI_TONE_DIALRECALL, +}; + +struct dahdi_vmwi_info mwisend_setting; /*!< Which VMWI methods to use */ + +/* Use to translate a DTMF character to the value required by the dahdi call */ +static int digit_to_dtmfindex(char digit) +{ + if (isdigit(digit)) + return DAHDI_TONE_DTMF_BASE + (digit - '0'); + else if (digit >= 'A' && digit <= 'D') + return DAHDI_TONE_DTMF_A + (digit - 'A'); + else if (digit >= 'a' && digit <= 'd') + return DAHDI_TONE_DTMF_A + (digit - 'a'); + else if (digit == '*') + return DAHDI_TONE_DTMF_s; + else if (digit == '#') + return DAHDI_TONE_DTMF_p; + else + return -1; +} + +/* Place a channel into ringing mode */ +static int dahdi_ring_phone(int fd) +{ + int x; + int res; + /* Make sure our transmit state is on hook */ + x = 0; + x = DAHDI_ONHOOK; + res = ioctl(fd, DAHDI_HOOK, &x); + do { + x = DAHDI_RING; + res = ioctl(fd, DAHDI_HOOK, &x); + if (res) { + switch (errno) { + case EBUSY: + case EINTR: + /* Wait just in case */ + fprintf(stderr, "Ring phone is busy:%s\n", strerror(errno)); + usleep(10000); + continue; + case EINPROGRESS: + fprintf(stderr, "Ring In Progress:%s\n", strerror(errno)); + res = 0; + break; + default: + fprintf(stderr, "Couldn't ring the phone: %s\n", strerror(errno)); + res = 0; + } + } else { + fprintf(stderr, "Phone is ringing\n"); + } + } while (res); + return res; +} + +int channel_open(const char *name) +{ + int channo, fd; + struct stat filestat; + const char *DEVICE = "/dev/dahdi/channel"; + + /* stat file, if character device, open it */ + channo = strtoul(name, NULL, 10); + fd = stat(name, &filestat); + if (!fd && S_ISCHR(filestat.st_mode)) { + fd = open(name, O_RDWR, 0600); + if (fd < 0) { + perror(name); + return -1; + } + /* try out the dahdi_specify interface */ + } else if (channo > 0) { + fd = open(DEVICE, O_RDWR, 0600); + if (fd < 0) { + perror(DEVICE); + return -1; + } + if (ioctl(fd, DAHDI_SPECIFY, &channo) < 0) { + perror("DAHDI_SPECIFY ioctl failed"); + return -1; + } + /* die */ + } else { + fprintf(stderr, "Specified channel is not a valid character " + "device or channel number"); + return -1; + } + return fd; +} + +int main(int argc, char *argv[]) +{ + int fd; + int res; + int x; + if (argc < 3) { + fprintf(stderr, "Usage: fxstest \n" + " where cmd is one of:\n" + " stats - reports voltages\n" + " regdump - dumps ProSLIC registers\n" + " tones - plays a series of tones\n" + " polarity - tests polarity reversal\n" + " ring - rings phone\n" + " vmwi - toggles VMWI LED lamp\n" + " hvdc - toggles VMWI HV lamp\n" + " neon - toggles VMWI NEON lamp\n" + " dtmf []- Send a sequence of dtmf tones (\"-\" denotes no tone)\n" + " dtmfcid - create a dtmf cid spill without polarity reversal\n"); + exit(1); + } + fd = channel_open(argv[1]); + if (fd < 0) { + fprintf(stderr, "Unable to open %s: %s\n", argv[1], strerror(errno)); + exit(1); + } + + if ( !strcasecmp(argv[2], "neon") || !strcasecmp(argv[2], "vmwi") || !strcasecmp(argv[2], "hvdc")) { + fprintf(stderr, "Twiddling %s ...\n", argv[2]); + + if ( !strcasecmp(argv[2], "vmwi") ) { + mwisend_setting.vmwi_type = DAHDI_VMWI_LREV; + } else if ( !strcasecmp(argv[2], "neon") ) { + mwisend_setting.vmwi_type = DAHDI_VMWI_HVAC; + } else if ( !strcasecmp(argv[2], "hvdc") ) { + mwisend_setting.vmwi_type = DAHDI_VMWI_HVDC; + } + res = ioctl(fd, DAHDI_VMWI_CONFIG, &mwisend_setting); + + x = 1; + res = ioctl(fd, DAHDI_VMWI, &x); + if (res) { + fprintf(stderr, "Unable to set %s ...\n", argv[2]); + } else { + fprintf(stderr, "Set 1 Voice Message...\n"); + + sleep(5); + x = 2; + ioctl(fd, DAHDI_VMWI, &x); + fprintf(stderr, "Set 2 Voice Messages...\n"); + + sleep(5); + x = 0; + ioctl(fd, DAHDI_VMWI, &x); + fprintf(stderr, "Set No Voice messages...\n"); + sleep(2); + mwisend_setting.vmwi_type = 0; + } + } else if (!strcasecmp(argv[2], "ring")) { + fprintf(stderr, "Ringing phone...\n"); + x = DAHDI_RING; + res = ioctl(fd, DAHDI_HOOK, &x); + if (res) { + fprintf(stderr, "Unable to ring phone...\n"); + } else { + fprintf(stderr, "Phone is ringing...\n"); + sleep(2); + } + } else if (!strcasecmp(argv[2], "polarity")) { + fprintf(stderr, "Twiddling polarity...\n"); + /* Insure that the channel is in active mode */ + x = DAHDI_RING; + res = ioctl(fd, DAHDI_HOOK, &x); + usleep(100000); + x = 0; + res = ioctl(fd, DAHDI_HOOK, &x); + + x = 0; + res = ioctl(fd, DAHDI_SETPOLARITY, &x); + if (res) { + fprintf(stderr, "Unable to polarity...\n"); + } else { + fprintf(stderr, "Polarity is forward...\n"); + sleep(2); + x = 1; + ioctl(fd, DAHDI_SETPOLARITY, &x); + fprintf(stderr, "Polarity is reversed...\n"); + sleep(5); + x = 0; + ioctl(fd, DAHDI_SETPOLARITY, &x); + fprintf(stderr, "Polarity is forward...\n"); + sleep(2); + } + } else if (!strcasecmp(argv[2], "tones")) { + int x = 0; + for (;;) { + res = tone_zone_play_tone(fd, tones[x]); + if (res) + fprintf(stderr, "Unable to play tone %d\n", tones[x]); + sleep(3); + x=(x+1) % (sizeof(tones) / sizeof(tones[0])); + } + } else if (!strcasecmp(argv[2], "stats")) { + struct wctdm_stats stats; + res = ioctl(fd, WCTDM_GET_STATS, &stats); + if (res) { + fprintf(stderr, "Unable to get stats on channel %s\n", argv[1]); + } else { + printf("TIP: %7.4f Volts\n", (float)stats.tipvolt / 1000.0); + printf("RING: %7.4f Volts\n", (float)stats.ringvolt / 1000.0); + printf("VBAT: %7.4f Volts\n", (float)stats.batvolt / 1000.0); + } + } else if (!strcasecmp(argv[2], "regdump")) { + struct wctdm_regs regs; + int numregs = NUM_REGS; + memset(®s, 0, sizeof(regs)); + res = ioctl(fd, WCTDM_GET_REGS, ®s); + if (res) { + fprintf(stderr, "Unable to get registers on channel %s\n", argv[1]); + } else { + for (x=60;x= 5) { + sscanf(argv[4], "%30i", &duration); + } + printf("Going to send a set of DTMF tones >%s<\n", outstring); + printf("Using a duration of %d mS per tone\n", duration); + /* Flush any left remaining characs in the buffer and place the channel into on-hook transfer mode */ + x = DAHDI_FLUSH_BOTH; + res = ioctl(fd, DAHDI_FLUSH, &x); + x = 500 + strlen(outstring) * duration; + ioctl(fd, DAHDI_ONHOOKTRANSFER, &x); + + for (x = 0; '\0' != outstring[x]; x++) { + dtmftone = digit_to_dtmfindex(outstring[x]); + if (0 > dtmftone) { + dtmftone = -1; + } + res = tone_zone_play_tone(fd, dtmftone); + if (res) { + fprintf(stderr, "Unable to play DTMF tone %d (0x%x)\n", dtmftone, dtmftone); + } + usleep(duration * 1000); + } + } + } else if (!strcasecmp(argv[2], "dtmfcid")) { + char * outstring = "A5551212C"; /* Default string using A and C tones to bracket the number */ + int dtmftone; + + if(argc >= 4) { /* Use user supplied string */ + outstring = argv[3]; + } + printf("Going to send a set of DTMF tones >%s<\n", outstring); + /* Flush any left remaining characs in the buffer and place the channel into on-hook transfer mode */ + x = DAHDI_FLUSH_BOTH; + res = ioctl(fd, DAHDI_FLUSH, &x); + x = 500 + strlen(outstring) * 100; + ioctl(fd, DAHDI_ONHOOKTRANSFER, &x); + + /* Play the DTMF tones at a 50 mS on and 50 mS off rate which is standard for DTMF CID spills */ + for (x = 0; '\0' != outstring[x]; x++) { + + dtmftone = digit_to_dtmfindex(outstring[x]); + if (0 > dtmftone) { + dtmftone = -1; + } + res = tone_zone_play_tone(fd, dtmftone); + if (res) { + fprintf(stderr, "Unable to play DTMF tone %d (0x%x)\n", dtmftone, dtmftone); + } + usleep(50000); + tone_zone_play_tone(fd, -1); + usleep(50000); + } + /* Wait for 150 mS from end of last tone to initiating the ring */ + usleep(100000); + dahdi_ring_phone(fd); + sleep(10); + printf("Ringing Done\n"); + } else + fprintf(stderr, "Invalid command\n"); + close(fd); + return 0; +} diff --git a/hdlcgen.c b/hdlcgen.c new file mode 100644 index 0000000..29811bb --- /dev/null +++ b/hdlcgen.c @@ -0,0 +1,135 @@ +/* + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include + +#define FAST_HDLC_NEED_TABLES +#include + +#include "dahdi_tools_version.h" + +#define RANDOM "/dev/urandom" /* Not genuinely random */ +/* #define RANDOM "/dev/random" */ /* Quite genuinely random */ + +int myread(int fd, char *buf, int len) +{ + int sofar; + int res; + sofar = 0; + while(sofar < len) { + res = read(fd, buf + sofar, len - sofar); + if (res < 0) + return res; + sofar += res; + } + return sofar; +} + +int main(int argc, char *argv[]) +{ + unsigned char buf[1024]; + unsigned char outbuf[2048]; + int res; + int randin; + int randout; + int hdlcout; + int cnt; + int hdlccnt; + int x; + int flags; + struct fasthdlc_state transmitter; + + fasthdlc_precalc(); + + fasthdlc_init(&transmitter, FASTHDLC_MODE_64); + + randin = open(RANDOM, O_RDONLY); + if (randin < 0) { + fprintf(stderr, "Unable to open %s: %s\n", RANDOM, strerror(errno)); + exit(1); + } + randout = open("random.raw", O_WRONLY|O_TRUNC|O_CREAT, 0666); + if (randout < 0) { + fprintf(stderr, "Unable to open random.raw: %s\n", strerror(errno)); + exit(1); + } + hdlcout = open("random.hdlc", O_WRONLY|O_TRUNC|O_CREAT, 0666); + if (hdlcout < 0) { + fprintf(stderr, "Unable to open random.hdlc: %s\n", strerror(errno)); + exit(1); + } + for (;;) { + cnt = (rand() % 256) + 4; /* Read a pseudo-random amount of stuff */ + res = myread(randin, buf, cnt); + if (res != cnt) { + fprintf(stderr, "Tried to read %d bytes, but read %d instead\n", cnt, res); + exit(1); + } + res = write(randout, buf, cnt); + if (res != cnt) { + fprintf(stderr, "Tried to write %d bytes, but wrote %d instead\n", cnt, res); + exit(1); + } + /* HDLC encode */ + hdlccnt = 0; + /* Start with a flag */ + fasthdlc_tx_frame(&transmitter); + if (transmitter.bits >= 8) + outbuf[hdlccnt++] = fasthdlc_tx_run(&transmitter); + for (x=0;x= 8) { + outbuf[hdlccnt++] = fasthdlc_tx_run(&transmitter); + } + } + flags = (rand() % 4); + for (x=0;x 1) + printf("Encoded %d byte message with %d bytes of HDLC and %d extra flags\n", cnt, hdlccnt, flags); + res = write(hdlcout, outbuf, hdlccnt); + if (res != hdlccnt) { + fprintf(stderr, "Tried to write %d HDLC bytes, but wrote %d instead\n", cnt, res); + exit(1); + } + + } +} diff --git a/hdlcstress.c b/hdlcstress.c new file mode 100644 index 0000000..6704f1f --- /dev/null +++ b/hdlcstress.c @@ -0,0 +1,233 @@ +/* + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FAST_HDLC_NEED_TABLES +#include + +#include "bittest.h" + + +#include "dahdi_tools_version.h" + +/* #define BLOCK_SIZE 2048 */ +#define BLOCK_SIZE 2041 + +static int hdlcmode = 0; +static int bri_delay = 0; + + +static unsigned short fcstab[256] = +{ + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; + +#define PPP_INITFCS 0xffff /* Initial FCS value */ +#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ +#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) + +void print_packet(unsigned char *buf, int len) +{ + int x; + printf("{ "); + for (x=0;x 7) + outbuf[pos++] = fasthdlc_tx_run(&fs); + } + fcs ^= 0xffff; + if (fasthdlc_tx_load(&fs, (fcs & 0xff))) + fprintf(stderr, "Load error (fcs1)\n"); + outbuf[pos++] = fasthdlc_tx_run(&fs); + if (fs.bits > 7) + outbuf[pos++] = fasthdlc_tx_run(&fs); + if (fasthdlc_tx_load(&fs, ((fcs >> 8) & 0xff))) + fprintf(stderr, "Load error (fcs2)\n"); + outbuf[pos++] = fasthdlc_tx_run(&fs); + if (fs.bits > 7) + outbuf[pos++] = fasthdlc_tx_run(&fs); + if (fasthdlc_tx_frame(&fs)) + fprintf(stderr, "Frame error\n"); + if (fs.bits > 7) + outbuf[pos++] = fasthdlc_tx_run(&fs); + if (fs.bits > 7) + outbuf[pos++] = fasthdlc_tx_run(&fs); + write(fd, outbuf, pos); + } +} + +int main(int argc, char *argv[]) +{ + int res, ch, x; + struct dahdi_params tp; + struct dahdi_bufferinfo bi; + int bs = BLOCK_SIZE; + unsigned char c=0; + unsigned char outbuf[BLOCK_SIZE]; + + while((ch = getopt(argc, argv, "b")) != -1) { + switch(ch) { + case 'b': bri_delay = 300000; break; + case '?': exit(1); + } + } + + if (argc - optind != 1) { + fprintf(stderr, "Usage: %s [-b] \n", argv[0]); + exit(1); + } + fd = open(argv[optind], O_RDWR, 0600); + if (fd < 0) { + fprintf(stderr, "Unable to open %s: %s\n", argv[optind], strerror(errno)); + exit(1); + } + if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs)) { + fprintf(stderr, "Unable to set block size to %d: %s\n", bs, strerror(errno)); + exit(1); + } + if (ioctl(fd, DAHDI_GET_PARAMS, &tp)) { + fprintf(stderr, "Unable to get channel parameters\n"); + exit(1); + } + if ((tp.sigtype & DAHDI_SIG_HDLCRAW) == DAHDI_SIG_HDLCRAW) { + printf("In HDLC mode\n"); + hdlcmode = 1; + } else if ((tp.sigtype & DAHDI_SIG_CLEAR) == DAHDI_SIG_CLEAR) { + printf("In CLEAR mode\n"); + hdlcmode = 0; + } else { + fprintf(stderr, "Not in a reasonable mode\n"); + exit(1); + } + res = ioctl(fd, DAHDI_GET_BUFINFO, &bi); + if (!res) { + bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; + bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; + bi.numbufs = 4; + res = ioctl(fd, DAHDI_SET_BUFINFO, &bi); + if (res < 0) { + fprintf(stderr, "Unable to set buf info: %s\n", strerror(errno)); + exit(1); + } + } else { + fprintf(stderr, "Unable to get buf info: %s\n", strerror(errno)); + exit(1); + } + ioctl(fd, DAHDI_GETEVENT); + fasthdlc_precalc(); + fasthdlc_init(&fs, FASTHDLC_MODE_64); +#if 0 + print_packet(outbuf, res); + printf("FCS is %x, PPP_GOODFCS is %x\n", + fcs,PPP_GOODFCS); +#endif + for(;;) { + if (c < 1) + c = 1; + for (x=0;x<50;x++) { + outbuf[x] = c; + } + send_packet(outbuf, 50); +#if 0 + printf("Wrote %d of %d bytes\n", res, c); +#endif + /* The HFC chip can't be bombarded too much. If a write has + failed, let it recover */ + if (bri_delay) + usleep(bri_delay); + + c = bit_next(c); +#if 0 + printf("(%d) Wrote %d bytes\n", packets++, res); +#endif + } + +} diff --git a/hdlctest.c b/hdlctest.c new file mode 100644 index 0000000..7358fc1 --- /dev/null +++ b/hdlctest.c @@ -0,0 +1,302 @@ +/* + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FAST_HDLC_NEED_TABLES +#include + +#include "bittest.h" + +#include "dahdi_tools_version.h" + +#define BLOCK_SIZE 2039 + +static unsigned short fcstab[256] = +{ + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; + +#define PPP_INITFCS 0xffff /* Initial FCS value */ +#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ +#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) + +void print_packet(unsigned char *buf, int len) +{ + int x; + printf("{ "); + for (x = 0; x < len; x++) { + printf("%02x ", buf[x]); + } + printf("}\n"); +} + +static int bytes; +static int errors; +static int c; + +void dump_bits(unsigned char *outbuf, int len) +{ + int x, i; + for (x = 0; x < len; x++) { + for (i = 0; i < 8; i++) { + if (outbuf[x] & (1 << (7 - i))) { + printf("1"); + } else { + printf("0"); + } + } + } + printf("\n"); +} + +void dump_bitslong(unsigned int outbuf, int bits) +{ + int i; + printf("Dumping %d bits from %04x\n", bits, outbuf); + for (i = 0; i < bits; i++) { + if (outbuf & (1 << (31 - i))) { + printf("1"); + } else { + printf("0"); + } + } + printf("\n"); +} + +int check_frame(unsigned char *outbuf, int res) +{ + static int setup = 0; + int x; + unsigned short fcs = PPP_INITFCS; + if (c < 1) { + c = 1; + } + if (!setup) { + c = outbuf[0]; + setup++; + } + for (x = 0; x < res; x++) { + if (outbuf[x] != c && (x < res - 2)) { + printf("(Error %d): Unexpected result, %d != %d, position %d %d bytes since last error.\n", + ++errors, outbuf[x], c, x, bytes); + if (!x) { + c = outbuf[0]; + } + bytes = 0; + } else { + bytes++; + } + fcs = PPP_FCS(fcs, outbuf[x]); + } + if (fcs != PPP_GOODFCS) { + printf("FCS Check failed :( (%04x != %04x)\n", fcs, PPP_GOODFCS); + } +#if 0 + if (res != c) { + printf("Res is %d, expected %d\n", res, c+2); + } +#endif + c = bit_next(c); + return 0; +} + +int main(int argc, char *argv[]) +{ + int fd; + int res, x; + struct dahdi_params tp; + struct dahdi_bufferinfo bi; + int bs = BLOCK_SIZE; + int pos = 0; + unsigned char inbuf[BLOCK_SIZE]; + unsigned char outbuf[BLOCK_SIZE]; + int bytes = 0; + int out; + unsigned int olddata1; + int oldones1; + int oldbits1; + unsigned int olddata = 0; + int oldones = 0; + int oldbits = 0; + int hdlcmode = 0; + struct fasthdlc_state fs; + if (argc < 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + fd = open(argv[1], O_RDWR, 0600); + if (fd < 0) { + fprintf(stderr, "Unable to open %s: %s\n", argv[1], strerror(errno)); + exit(1); + } + if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs)) { + fprintf(stderr, "Unable to set block size to %d: %s\n", bs, strerror(errno)); + exit(1); + } + if (ioctl(fd, DAHDI_GET_PARAMS, &tp)) { + fprintf(stderr, "Unable to get channel parameters\n"); + exit(1); + } + if ((tp.sigtype & DAHDI_SIG_HDLCRAW) == DAHDI_SIG_HDLCRAW) { + printf("In HDLC mode\n"); + hdlcmode = 1; + } else if ((tp.sigtype & DAHDI_SIG_CLEAR) == DAHDI_SIG_CLEAR) { + printf("In CLEAR mode\n"); + hdlcmode = 0; + } else { + fprintf(stderr, "Not in a reasonable mode\n"); + exit(1); + } + res = ioctl(fd, DAHDI_GET_BUFINFO, &bi); + if (!res) { + bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; + bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; + bi.numbufs = 4; + res = ioctl(fd, DAHDI_SET_BUFINFO, &bi); + if (res < 0) { + fprintf(stderr, "Unable to set buf info: %s\n", strerror(errno)); + exit(1); + } + } else { + fprintf(stderr, "Unable to get buf info: %s\n", strerror(errno)); + exit(1); + } + ioctl(fd, DAHDI_GETEVENT); + fasthdlc_precalc(); + fasthdlc_init(&fs, FASTHDLC_MODE_64); + for (;;) { + res = read(fd, outbuf, sizeof(outbuf)); + if (hdlcmode) { + if (res < 0) { + if (errno == ELAST) { + if (ioctl(fd, DAHDI_GETEVENT, &x) < 0) { + fprintf(stderr, "Unaable to get event: %s\n", strerror(errno)); + exit(1); + } + fprintf(stderr, "Event: %d (%d bytes since last error)\n", x, bytes); + bytes = 0; + continue; + } else { + fprintf(stderr, "Error: %s\n", strerror(errno)); + exit(1); + } + } +#if 0 + printf("Res is %d, buf0 is %d, buf1 is %d\n", res, outbuf[0], outbuf[1]); +#endif + if (res < 2) { + fprintf(stderr, "Too small? Only got %d bytes\n", res); + } + check_frame(outbuf, res); + } else { + for (x = 0; x < res; x++) { + oldones1 = oldones; + oldbits1 = oldbits; + olddata1 = olddata; + oldones = fs.ones; + oldbits = fs.bits; + olddata = fs.data; + fasthdlc_rx_load(&fs, outbuf[x]); + out = fasthdlc_rx_run(&fs); + if (out & RETURN_EMPTY_FLAG) { + /* Empty */ + } else if (out & RETURN_COMPLETE_FLAG) { + if (pos && (pos < 2)) { + printf("Too short? (%d)\n", pos); + } else if (pos) { + check_frame(inbuf, pos); + } + pos = 0; + } else if (out & RETURN_DISCARD_FLAG) { + printf("Discard (search = %d, len = %d, buf = %d, x=%d, res=%d, oldones: %d, oldbits: %d)\n", + c, pos, inbuf[0], x, res, oldones, oldbits); + dump_bitslong(olddata, oldbits); + printf("Discard oldones: %d, oldbits: %d)\n", + oldones1, oldbits1); + dump_bitslong(olddata1, oldbits1); + if (x > 64) { + dump_bits(outbuf + x - 64, 64); + dump_bits(outbuf + x, 64); + } + pos = 0; + } else { + if ((out != c) && (pos < c) && !pos) { + printf("Warning: Expecting %d at pos %d, got %d (x =%d)\n", c, pos, out, x); + if (x > 64) { + dump_bits(outbuf + x - 64, 64); + dump_bits(outbuf + x, 64); + } + } + inbuf[pos++] = out; + } + } + } + } + +} diff --git a/hdlcverify.c b/hdlcverify.c new file mode 100644 index 0000000..a7401fe --- /dev/null +++ b/hdlcverify.c @@ -0,0 +1,136 @@ +/* + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include + +#define FAST_HDLC_NEED_TABLES +#include + +#include "dahdi_tools_version.h" + +int myread(int fd, unsigned char *buf, int len) +{ + int sofar; + int res; + sofar = 0; + while(sofar < len) { + res = read(fd, buf + sofar, len - sofar); + if (res < 0) + return res; + sofar += res; + } + return sofar; +} + +static inline unsigned char nextchar(int fd) +{ + static unsigned char inbuf[2048]; + static int bytes = 0; + static int pos = 0; + if (pos >= bytes) { + pos = 0; + bytes = read(fd, inbuf, sizeof(inbuf)); + if (bytes < 0) { + fprintf(stderr, "Unable to read more data: %s\n", strerror(errno)); + exit(1); + } + if (bytes == 0) { + fprintf(stderr, "-- END OF DATA --\n"); + exit(0); + } + } + return inbuf[pos++]; +} + +int main(int argc, char *argv[]) +{ + unsigned char decbuf[1024]; + unsigned char actual[1024]; + int res; + int datain; + int hdlcin; + int hdlccnt; + int x; + struct fasthdlc_state receiver; + + fasthdlc_precalc(); + + fasthdlc_init(&receiver, FASTHDLC_MODE_64); + + hdlcin = open("random.hdlc", O_RDONLY); + if (hdlcin < 0) { + fprintf(stderr, "Unable to open %s: %s\n", "random.hdlc", strerror(errno)); + exit(1); + } + datain = open("random.raw", O_RDONLY); + if (datain < 0) { + fprintf(stderr, "Unable to open random.raw: %s\n", strerror(errno)); + exit(1); + } + hdlccnt = 0; + for (;;) { + /* Feed in some input */ + if (fasthdlc_rx_load(&receiver, nextchar(hdlcin))) { + fprintf(stderr, "Unable to feed receiver :(\n"); + exit(1); + } + res = fasthdlc_rx_run(&receiver); + if (res & RETURN_EMPTY_FLAG) + continue; + if (res & RETURN_COMPLETE_FLAG) { + if (hdlccnt) { + if (argc > 1) + printf("Got message of length %d\n", hdlccnt); + res = myread(datain, actual, hdlccnt); + if (res != hdlccnt) { + fprintf(stderr, "Tried to read %d bytes, but read %d instead\n", hdlccnt, res); + exit(1); + } + for (x=0;x/dev/null | \ + sed 's,/registration_time:,\t,' | \ + sort -k 2,2 +} + +# First assign non-Astribank devices +devices_by_registration_time | \ + grep -v '/astribanks:' | \ + while read devpath time; do + echo >&2 "D: auto '$devpath'" + dahdi_span_assignments auto "$devpath" + done + +# Now handle Astribanks +LC_ALL=C dahdi_registration -Rv on diff --git a/hotplug/dahdi_handle_device b/hotplug/dahdi_handle_device new file mode 100755 index 0000000..30329bd --- /dev/null +++ b/hotplug/dahdi_handle_device @@ -0,0 +1,87 @@ +#! /bin/sh +# +# /usr/share/dahdi/dahdi_handle_device +# +# Called by UDEV when a dahdi device is added/removed +# + +me=`basename $0` +dir=`dirname $0` +LOGGER="logger -i -t '$me'" +NAME=`basename "$DEVPATH" | tr -c 'A-Za-z0-9-' '_'` + +# Always redirect stderr somewhere, otherwise the shell script will die +# when it tries to do I/O related stuff on closed file descriptor. +# Our default is to throw it down the bit-bucket. +exec 2> /dev/null +# If you wish to trace this script: +#exec 2> "/tmp/${me}.$NAME" 1>&2 +#exec 2> /dev/console + +# Our directory in the beginning, so we can use local lab setup +PATH="$dir:/usr/sbin:/sbin:/usr/bin:/bin" +export PATH + +set -e + +#echo >&2 "$0($ACTION): DEBUG($# args): '$*'" + +# Do we have a configuration? +if [ -f /etc/dahdi/init.conf ]; then + . /etc/dahdi/init.conf +fi + +if [ "$DAHDI_UDEV_DISABLE_DEVICES" = 'yes' ]; then + echo "DAHDI_UDEV_DISABLE_DEVICES=yes. Skip $DEVPATH" | $LOGGER + exit 0 +fi + +# Can we pass a different value so we can use +# alternate (testing) configuration? +# Meanwhile, make it hard-coded. +DAHDICONFDIR='/etc/dahdi' +export DAHDICONFDIR + +run_parts() { + # Have our internal "run-parts" (adapted from Fedora), + # as implementations differ + for i in `LC_ALL=C; ls -d $dir/handle_device.d/*[!~,] 2>/dev/null` ; do + [ -d "$i" ] && continue + [ ! -x "$i" ] && continue + # Don't run *.{rpmsave,rpmorig,rpmnew,swp,cfsaved} files + case "$i" in + *.cfsaved|*.rpmsave|*.rpmorig|*.rpmnew|*.swp|*,v) + continue + ;; + esac + echo "D: Running '$i'" + "$i" + done +} + +case "$ACTION" in +add) + echo "$ACTION: $DEVPATH" | $LOGGER + + # Check if we can safely do our job + if [ ! -f /sys/module/dahdi/parameters/auto_assign_spans ]; then + echo "Old driver (no auto_assign_spans parameter). Skip $DEVPATH" | $LOGGER + exit 0 + fi + if [ `cat /sys/module/dahdi/parameters/auto_assign_spans` -ne 0 ]; then + echo "auto_assign_spans=1. Skip $DEVPATH" | $LOGGER + exit 0 + fi + + # Background run -- don't block udev + run_parts 2>&1 < /dev/null | $LOGGER & + ;; +remove) + echo "$ACTION: $DEVPATH" | $LOGGER + # Background run -- don't block udev + run_parts 2>&1 < /dev/null | $LOGGER & + ;; +*) + echo "UNHANDLED: $ACTION: $DEVPATH" | $LOGGER + ;; +esac diff --git a/hotplug/dahdi_span_config b/hotplug/dahdi_span_config new file mode 100755 index 0000000..25a10e2 --- /dev/null +++ b/hotplug/dahdi_span_config @@ -0,0 +1,97 @@ +#! /bin/sh +# +# /usr/share/dahdi/dahdi_span_config +# +# Called by UDEV when a dahdi span is added/removed +# + +me=`basename $0` +dir=`dirname $0` +LOGGER="logger -i -t '$me'" +NAME=`basename "$DEVPATH" | tr -c 'A-Za-z0-9-' '_'` + +exec 2> /dev/null +# Always redirect stderr somewhere, otherwise the shell script will die +# when it tries to do I/O related stuff on closed file descriptor. +# Our default is to throw it down the bit-bucket. +#exec 2> /dev/console +## If you wish to trace this script: +#exec 2> "/tmp/${me}.$NAME" 1>&2 + +# Our directory in the beginning, so we can use local lab setup +PATH="$dir:/usr/sbin:/sbin:/usr/bin:/bin" +export PATH + +set -e + +#echo >&2 "$0($ACTION): DEBUG($# args): '$*'" + +# Do we have a configuration? +if [ -f /etc/dahdi/init.conf ]; then + . /etc/dahdi/init.conf +fi + +if [ "$DAHDI_UDEV_DISABLE_SPANS" = 'yes' ]; then + echo "DAHDI_UDEV_DISABLE_SPANS=yes. Skip $DEVPATH" | $LOGGER + exit 0 +fi + +# Can we pass a different value so we can use +# alternate (testing) configuration? +# Meanwhile, make it hard-coded. +DAHDICONFDIR='/etc/dahdi' +export DAHDICONFDIR + +run_parts() { + # Have our internal "run-parts" (adapted from Fedora), + # as implementations differ + for i in `LC_ALL=C; ls -d $dir/span_config.d/*[!~,] 2>/dev/null` ; do + [ -d "$i" ] && continue + [ ! -x "$i" ] && continue + # Don't run *.{rpmsave,rpmorig,rpmnew,swp,cfsaved} files + case "$i" in + *.cfsaved|*.rpmsave|*.rpmorig|*.rpmnew|*.swp|*,v) + continue + ;; + esac + #echo "D: Running '$i'" + "$i" + done +} + +case "$ACTION" in +add) + echo "$ACTION: $DEVPATH" | $LOGGER + + # Old driver. These scripts probably won't work anyway. + if [ ! -f /sys/module/dahdi/parameters/auto_assign_spans ]; then + if [ -f /sys/module/dahdi ]; then + $LOGGER "Old driver (no auto_assign_spans parameter). Skip $DEVPATH" + exit 0 + fi + fi + + if [ $(cat /sys/module/dahdi/parameters/auto_assign_spans) -ne 0 ]; then + $LOGGER "auto_assign_spans=1. Skip $DEVPATH" + exit 0 + fi + + # Set variables + span_devpath="/sys$DEVPATH" + SPANNO=`echo "$span_devpath" | sed 's,.*/span-,,'` + BASECHAN=`cat "$span_devpath/basechan"` + CHANNELS=`cat "$span_devpath/channels"` + ENDCHAN=`expr "$BASECHAN" + "$CHANNELS" - 1` + export SPANNO BASECHAN CHANNELS ENDCHAN + # Background run -- don't block udev + run_parts 2>&1 < /dev/null | $LOGGER & + ;; +remove|online|offline) + # Nothing to do yet... + echo "$ACTION: $DEVPATH" | $LOGGER + ;; +*) + echo "UNHANDLED: $ACTION: $DEVPATH" | $LOGGER + ;; +esac + diff --git a/hotplug/handle_device.d/10-span-types b/hotplug/handle_device.d/10-span-types new file mode 100755 index 0000000..6b78021 --- /dev/null +++ b/hotplug/handle_device.d/10-span-types @@ -0,0 +1,12 @@ +#! /bin/sh + +case "$ACTION" in +add) + ;; +*) + exit 0 +esac + +if [ -r "$DAHDICONFDIR/span-types.conf" ]; then + dahdi_span_types set "/sys$DEVPATH" +fi diff --git a/hotplug/handle_device.d/20-span-assignments b/hotplug/handle_device.d/20-span-assignments new file mode 100755 index 0000000..5493232 --- /dev/null +++ b/hotplug/handle_device.d/20-span-assignments @@ -0,0 +1,15 @@ +#! /bin/sh + +case "$ACTION" in +add) + ;; +*) + exit 0 +esac + +# For now, handle only spans in assigned-spans.conf +# We leave other cases to /etc/init.d/dahdi, so +# legacy ordering can be preserved. +if [ -r "$DAHDICONFDIR/assigned-spans.conf" ]; then + dahdi_span_assignments add "/sys$DEVPATH" +fi diff --git a/hotplug/span_config.d/10-dahdi-cfg b/hotplug/span_config.d/10-dahdi-cfg new file mode 100755 index 0000000..9ca2efe --- /dev/null +++ b/hotplug/span_config.d/10-dahdi-cfg @@ -0,0 +1,28 @@ +#! /bin/sh + +if [ "$ACTION" != 'add' ]; then + # Nothing to do here + exit 0 +fi + +# Sanity check +checkit=`"dahdi_cfg" --help 2>&1 | grep -- '-S' | wc -l` +if [ "$checkit" != 1 ]; then + echo "Bad dahdi_cfg (no -S support). Skipping" + exit 0 +fi + +run_dahdi_cfg() { + echo "dahdi_cfg: span $SPANNO <$BASECHAN-$ENDCHAN> ($DEVPATH)" + dahdi_cfg -c "$cfg_file" -S "$SPANNO" -C "$BASECHAN-$ENDCHAN" +} + +# Configure DAHDI +cfg_file="$DAHDICONFDIR/system.conf" +if [ -r "$cfg_file" ]; then + run_dahdi_cfg +else + echo "Using auto-generated config for dahdi_cfg" + cfg_file='-' + DAHDI_CONF_FILE="$cfg_file" dahdi_genconf system | run_dahdi_cfg +fi diff --git a/hotplug/span_config.d/20-fxotune b/hotplug/span_config.d/20-fxotune new file mode 100755 index 0000000..199c82c --- /dev/null +++ b/hotplug/span_config.d/20-fxotune @@ -0,0 +1,12 @@ +#! /bin/sh + +if [ "$ACTION" != 'add' ]; then + # Nothing to do here + exit 0 +fi + +fxotune_cfg='/etc/fxotune.conf' +if [ -r "$fxotune_cfg" ]; then + echo "fxotune: span $SPANNO <$BASECHAN-$ENDCHAN> ($DEVPATH)" + fxotune -s -b "$BASECHAN" -e "$ENDCHAN" +fi diff --git a/hotplug/span_config.d/50-asterisk b/hotplug/span_config.d/50-asterisk new file mode 100755 index 0000000..3b75899 --- /dev/null +++ b/hotplug/span_config.d/50-asterisk @@ -0,0 +1,14 @@ +#! /bin/sh + +# This file, if installed under /usr/share/dahdi/span_config.d/ , will +# attempt to add a newly-generated span to a running copy of Asterisk. +# Asterisk has to be running (if not: it will pick the span on its +# startup), and has to have the channels already configured. + +if [ "$ACTION" != 'add' ]; then + # Nothing to do here + exit 0 +fi + +# Add to asterisk +asterisk -rx "dahdi create channels $BASECHAN $ENDCHAN" diff --git a/ifup-hdlc b/ifup-hdlc new file mode 100644 index 0000000..6602c46 --- /dev/null +++ b/ifup-hdlc @@ -0,0 +1,39 @@ +#!/bin/sh +PATH=/sbin:/usr/sbin:/bin:/usr/bin + +cd /etc/sysconfig/network-scripts +. network-functions + +CONFIG=$1 +source_config + +if [ "foo$2" = "fooboot" -a "${ONBOOT}" = "no" ] +then + exit +fi + +if [ -z "${MODE}" ]; then + echo "No mode specified!" + exit +fi + +sethdlc ${DEVICE} mode ${MODE} +ifconfig ${DEVICE} ${IPADDR} pointopoint ${REMIP} +route add -net ${NETWORK} netmask ${NETMASK} ${DEVICE} + +# this is broken! it's only here to keep compatibility with old RH sytstems +if [ "${GATEWAY}" != "" -a "${GATEWAY}" != "none" ] +then + route add default gw ${GATEWAY} metric 1 ${DEVICE} +fi + +. /etc/sysconfig/network + +if [ "${GATEWAY}" != "" ]; then + if [ "${GATEWAYDEV}" = "" -o "${GATEWAYDEV}" = "${DEVICE}" ]; then + # set up default gateway + route add default gw ${GATEWAY} + fi +fi + +/etc/sysconfig/network-scripts/ifup-post $1 diff --git a/init.conf.sample b/init.conf.sample new file mode 100644 index 0000000..6bbb199 --- /dev/null +++ b/init.conf.sample @@ -0,0 +1,24 @@ +# +# Shell settings for Dahdi initialization scripts. +# This replaces the old/per-platform files (/etc/sysconfig/zaptel, +# /etc/defaults/zaptel) +# + +# The maximal timeout (seconds) to wait for udevd to finish generating +# device nodes after the modules have loaded and before running dahdi_cfg. +#DAHDI_DEV_TIMEOUT=40 + +# A list of modules to unload when stopping. +# All of their dependencies will be unloaded as well. +#DAHDI_UNLOAD_MODULES="" # Disable module unloading +#DAHDI_UNLOAD_MODULES="dahdi echo" # If you use OSLEC + +# Override settings for xpp_fxloader +#XPP_FIRMWARE_DIR=/usr/share/dahdi +#XPP_HOTPLUG_DISABLED=yes +#XPP_HOTPLUG_DAHDI=yes +#ASTERISK_SUPPORTS_DAHDI_HOTPLUG=yes + +# Disable udev handling: +#DAHDI_UDEV_DISABLE_DEVICES=yes +#DAHDI_UDEV_DISABLE_SPANS=yes diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..4d4a951 --- /dev/null +++ b/install-sh @@ -0,0 +1,323 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2005-05-14.22 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +chmodcmd="$chmodprog 0755" +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= +dstarg= +no_target_directory= + +usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: +-c (ignored) +-d create directories instead of installing files. +-g GROUP $chgrpprog installed files to GROUP. +-m MODE $chmodprog installed files to MODE. +-o USER $chownprog installed files to USER. +-s $stripprog installed files. +-t DIRECTORY install into DIRECTORY. +-T report an error if DSTFILE is a directory. +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test -n "$1"; do + case $1 in + -c) shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit $?;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t) dstarg=$2 + shift + shift + continue;; + + -T) no_target_directory=true + shift + continue;; + + --version) echo "$0 $scriptversion"; exit $?;; + + *) # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + test -n "$dir_arg$dstarg" && break + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done + break;; + esac +done + +if test -z "$1"; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + src= + + if test -d "$dst"; then + mkdircmd=: + chmodcmd= + else + mkdircmd=$mkdirprog + fi + else + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dstarg: Is a directory" >&2 + exit 1 + fi + dst=$dst/`basename "$src"` + fi + fi + + # This sed command emulates the dirname command. + dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` + + # Make sure that the destination directory exists. + + # Skip lots of stat calls in the usual case. + if test ! -d "$dstdir"; then + defaultIFS=' + ' + IFS="${IFS-$defaultIFS}" + + oIFS=$IFS + # Some sh's can't handle IFS=/ for some reason. + IFS='%' + set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` + shift + IFS=$oIFS + + pathcomp= + + while test $# -ne 0 ; do + pathcomp=$pathcomp$1 + shift + if test ! -d "$pathcomp"; then + $mkdirprog "$pathcomp" + # mkdir can fail with a `File exist' error in case several + # install-sh are creating the directory concurrently. This + # is OK. + test -d "$pathcomp" || exit + fi + pathcomp=$pathcomp/ + done + fi + + if test -n "$dir_arg"; then + $doit $mkdircmd "$dst" \ + && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } + + else + dstfile=`basename "$dst"` + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + trap '(exit $?); exit' 1 2 13 15 + + # Copy the file name to the temp name. + $doit $cpprog "$src" "$dsttmp" && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dstdir/$dstfile"; then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ + || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ + || { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit 1 + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + } + } + fi || { (exit 1); exit 1; } +done + +# The final little trick to "correctly" pass the exit status to the exit trap. +{ + (exit 0); exit 0 +} + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/makeopts.in b/makeopts.in new file mode 100644 index 0000000..a892a76 --- /dev/null +++ b/makeopts.in @@ -0,0 +1,49 @@ +CC=@CC@ +LD=@LD@ +HOSTCC=@HOSTCC@ +CFLAGS=@CFLAGS@ +LDFLAGS=@LDFLAGS@ + +INSTALL=@INSTALL@ +GREP=@GREP@ +SHELL=@SHELL@ +LN=@LN@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +datarootdir = @datarootdir@ +datadir = @datadir@ +includedir = @includedir@ +infodir = @infodir@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ + +DOWNLOAD=@DOWNLOAD@ + +DAHDI_DEVMODE=@DAHDI_DEVMODE@ +DAHDI_DECLARATION_AFTER_STATEMENT=@DAHDI_DECLARATION_AFTER_STATEMENT@ + +PBX_NEWT=@PBX_NEWT@ +NEWT_LIB=@NEWT_LIB@ +NEWT_INCLUDE=@NEWT_INCLUDE@ + +PBX_USB=@PBX_USB@ +USB_LIB=@USB_LIB@ +USB_INCLUDE=@USB_INCLUDE@ + +PBX_HDLC=@PBX_HDLC@ + +DAHDI_INCLUDE=@DAHDI_INCLUDE@ + +USE_SELINUX=@USE_SELINUX@ + +PPPD_VERSION=@PPPD_VERSION@ + +ASCIIDOC=@ASCIIDOC@ diff --git a/modprobe.conf.sample b/modprobe.conf.sample new file mode 100644 index 0000000..1570d00 --- /dev/null +++ b/modprobe.conf.sample @@ -0,0 +1,4 @@ +# You should place any module parameters for your DAHDI modules here +# Example: +# +# options wctdm24xxp latency=6 diff --git a/modules.sample b/modules.sample new file mode 100644 index 0000000..08692af --- /dev/null +++ b/modules.sample @@ -0,0 +1,63 @@ +# Contains the list of modules to be loaded / unloaded by /etc/init.d/dahdi. +# +# NOTE: Please add/edit /etc/modprobe.d/dahdi or /etc/modprobe.conf if you +# would like to add any module parameters. +# +# Format of this file: list of modules, each in its own line. +# Anything after a '#' is ignore, likewise trailing and leading +# whitespaces and empty lines. + +# Digium TE205P/TE207P/TE210P/TE212P: PCI dual-port T1/E1/J1 +# Digium TE405P/TE407P/TE410P/TE412P: PCI quad-port T1/E1/J1 +# Digium TE220: PCI-Express dual-port T1/E1/J1 +# Digium TE420: PCI-Express quad-port T1/E1/J1 +wct4xxp + +# Digium TE435 +# Digium TE235 +# Digium TE436 +# Digium TE236 +wcte43x + +# Digium TE120P: PCI single-port T1/E1/J1 +# Digium TE121: PCI-Express single-port T1/E1/J1 +# Digium TE122: PCI single-port T1/E1/J1 +wcte12xp + +# Digium TE131: PCI-Express single-port T1/E1/J1 +# Digium TE132: PCI single-port T1/E1/J1 +# Digium TE133: PCI-Express single-port T1/E1/J1 with hardware echocan +# Digium TE134: PCI single-port T1/E1/J1 with hardware echocan +wcte13xp + +# Digium T100P: PCI single-port T1 +# Digium E100P: PCI single-port E1 +wct1xxp + +# Digium TE110P: PCI single-port T1/E1/J1 +wcte11xp + +# Digium TDM2400P/AEX2400: up to 24 analog ports +# Digium TDM800P/AEX800: up to 8 analog ports +# Digium TDM410P/AEX410: up to 4 analog ports +wctdm24xxp + +# Digium A4A/A4B/A8A/A8B +wcaxx + +# X100P - Single port FXO interface +# X101P - Single port FXO interface +wcfxo + +# Digium TDM400P: up to 4 analog ports +wctdm + +# Digium B410P: 4 NT/TE BRI ports +wcb4xxp + +# Digium TC400B: G729 / G723 Transcoding Engine +wctc4xxp + +# Xorcom Astribank Devices +xpp_usb + diff --git a/patgen.c b/patgen.c new file mode 100644 index 0000000..2b619d3 --- /dev/null +++ b/patgen.c @@ -0,0 +1,175 @@ +/* + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "bittest.h" + +#include +#include "dahdi_tools_version.h" + +/* #define BLOCK_SIZE 2048 */ +#define BLOCK_SIZE 2041 +#define DEVICE "/dev/dahdi/channel" + +static const char rcsid[] = "$Id$"; +char *prog_name; + +static void usage(void) +{ + fprintf(stderr, "Usage: %s \n", prog_name); + fprintf(stderr, " e.g.: %s /dev/dahdi/55\n", prog_name); + fprintf(stderr, " %s 455\n", prog_name); + fprintf(stderr, "%s version %s\n", prog_name, rcsid); + exit(1); +} + +void print_packet(unsigned char *buf, int len) +{ + int x; + printf("{ "); + for (x=0;x 0) { + fd = open(DEVICE, O_RDWR, 0600); + if (fd < 0) { + perror(DEVICE); + return -1; + } + if (ioctl(fd, DAHDI_SPECIFY, &channo) < 0) { + perror("DAHDI_SPECIFY ioctl failed"); + return -1; + } + /* die */ + } else { + fprintf(stderr, "Specified channel is not a valid character " + "device or channel number"); + return -1; + } + + if (ioctl(fd, DAHDI_SET_BLOCKSIZE, bs) < 0) { + perror("SET_BLOCKSIZE"); + return -1; + } + + if (ioctl(fd, DAHDI_GET_PARAMS, &tp)) { + fprintf(stderr, "Unable to get channel parameters\n"); + return -1; + } + + return fd; +} + +int main(int argc, char *argv[]) +{ + int fd; + int res, res1, x; + int bs = BLOCK_SIZE; + unsigned char c=0; + unsigned char outbuf[BLOCK_SIZE]; + + prog_name = argv[0]; + + if (argc < 2) { + usage(); + } + + fd = channel_open(argv[1], &bs); + if (fd < 0) + exit(1); + + ioctl(fd, DAHDI_GETEVENT); +#if 0 + print_packet(outbuf, res); + printf("FCS is %x, PPP_GOODFCS is %x\n", + fcs,PPP_GOODFCS); +#endif + for(;;) { + res = bs; + for (x=0;x + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +/* + * This test sends a set of incrementing byte values out the specified + * dadhi device. The device is then read back and the read back characters + * are verified that they increment as well. + * If there is a break in the incrementing pattern, an error is flagged + * and the comparison starts at the last value read. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "dahdi_tools_version.h" + +#define BLOCK_SIZE 2039 +#define DEVICE "/dev/dahdi/channel" + +#define CONTEXT_SIZE 7 +/* Prints a set of bytes in hex format */ +static void print_packet(unsigned char *buf, int len) +{ + int x; + printf("{ "); + for (x=0;x= bufsize || 0 >= bufsize || 0 > offset ) { + return; + } + + low = offset - (CONTEXT_SIZE-1)/2; + if (0 > low) { + total += low; + low = 0; + } + if (low + total > bufsize) { + total = bufsize - low; + } + buf += low; + printf("Offset %d ", low); + print_packet(buf, total); + return; +} + +/* Shows how the program can be invoked */ +static void usage(const char * progname) +{ + printf("%s: Pattern loop test\n", progname); + printf("Usage: %s [-t ] [-r ] [-b ] [-vh?] \n", progname); + printf("\t-? - Print this usage summary\n"); + printf("\t-t - # of seconds for the test to run\n"); + printf("\t-r - # of test loops to run before a summary is printed\n"); + printf("\t-s - # of writes to skip before testing for results\n"); + printf("\t-v - Verbosity (repetitive v's add to the verbosity level e.g. -vvvv)\n"); + printf("\t-b <# buffer bytes> - # of bytes to display from buffers on each pass\n"); + printf("\n\t Also accepts old style usage:\n\t %s []\n", progname); +} + +int channel_open(const char *name, int *bs) +{ + int channo, fd; + struct dahdi_params tp; + struct stat filestat; + + /* stat file, if character device, open it */ + channo = strtoul(name, NULL, 10); + fd = stat(name, &filestat); + if (!fd && S_ISCHR(filestat.st_mode)) { + fd = open(name, O_RDWR, 0600); + if (fd < 0) { + perror(name); + return -1; + } + /* try out the dahdi_specify interface */ + } else if (channo > 0) { + fd = open(DEVICE, O_RDWR, 0600); + if (fd < 0) { + perror(DEVICE); + return -1; + } + if (ioctl(fd, DAHDI_SPECIFY, &channo) < 0) { + perror("DAHDI_SPECIFY ioctl failed"); + return -1; + } + /* die */ + } else { + fprintf(stderr, "Specified channel is not a valid character " + "device or channel number"); + return -1; + } + + if (ioctl(fd, DAHDI_SET_BLOCKSIZE, bs) < 0) { + perror("SET_BLOCKSIZE"); + return -1; + } + + if (ioctl(fd, DAHDI_GET_PARAMS, &tp)) { + fprintf(stderr, "Unable to get channel parameters\n"); + return -1; + } + + return fd; +} + +int main(int argc, char *argv[]) +{ + int fd; + int res, x; + int i; + int bs = BLOCK_SIZE; + int skipcount = 10; + unsigned char c=0,c1=0; + unsigned char inbuf[BLOCK_SIZE]; + unsigned char outbuf[BLOCK_SIZE]; + int setup=0; + unsigned long bytes=0; + int timeout=0; + int loop_errorcount; + int reportloops = 0; + int buff_disp = 0; + unsigned long currentloop = 0; + unsigned long total_errorcount = 0; + int verbose = 0; + char * device; + int opt; + int oldstyle_cmdline = 1; + unsigned int event_count = 0; + + /* Parse the command line arguments */ + while((opt = getopt(argc, argv, "b:s:t:r:v?h")) != -1) { + switch(opt) { + case 'h': + case '?': + usage(argv[0]); + exit(1); + break; + case 'b': + buff_disp = strtoul(optarg, NULL, 10); + if (BLOCK_SIZE < buff_disp) { + buff_disp = BLOCK_SIZE; + } + oldstyle_cmdline = 0; + break; + case 'r': + reportloops = strtoul(optarg, NULL, 10); + oldstyle_cmdline = 0; + break; + case 's': + skipcount = strtoul(optarg, NULL, 10); + oldstyle_cmdline = 0; + break; + case 't': + timeout = strtoul(optarg, NULL, 10); + oldstyle_cmdline = 0; + break; + case 'v': + verbose++; + oldstyle_cmdline = 0; + break; + } + } + + /* If no device was specified */ + if(NULL == argv[optind]) { + printf("You need to supply a dahdi device to test\n"); + usage(argv[0]); + exit (1); + } + + /* Get the dahdi device name */ + if (argv[optind]) + device = argv[optind]; + + /* To maintain backward compatibility with previous versions process old style command line */ + if (oldstyle_cmdline && argc > optind +1) { + timeout = strtoul(argv[optind+1], NULL, 10); + } + + time_t start_time = 0; + + fd = channel_open(device, &bs); + if (fd < 0) + exit(1); + ioctl(fd, DAHDI_GETEVENT); + + i = DAHDI_FLUSH_ALL; + if (ioctl(fd,DAHDI_FLUSH,&i) == -1) { + perror("DAHDI_FLUSH"); + exit(255); + } + + /* Mark time if program has a specified timeout */ + if(0 < timeout){ + start_time = time(NULL); + printf("Using Timeout of %d Seconds\n",timeout); + } + + /* ********* MAIN TESTING LOOP ************ */ + for(;;) { + /* Prep the data and write it out to dahdi device */ + res = bs; + for (x = 0; x < bs; x++) { + outbuf[x] = c1++; + } + +write_again: + res = write(fd,outbuf,bs); + if (res != bs) { + if (ELAST == errno) { + ioctl(fd, DAHDI_GETEVENT, &x); + if (event_count > 0) + printf("Event: %d\n", x); + ++event_count; + } else { + printf("W: Res is %d: %s\n", res, strerror(errno)); + } + goto write_again; + } + + /* If this is the start of the test then skip a number of packets before test results */ + if (skipcount) { + if (skipcount > 1) { + res = read(fd,inbuf,bs); + } + skipcount--; + if (!skipcount) { + printf("Going for it...\n"); + } + i = 1; + ioctl(fd,DAHDI_BUFFER_EVENTS, &i); + continue; + } + +read_again: + res = read(fd, inbuf, bs); + if (res < bs) { + printf("R: Res is %d\n", res); + ioctl(fd, DAHDI_GETEVENT, &x); + printf("Event: %d\n", x); + goto read_again; + } + /* If first time through, set byte that is used to test further bytes */ + if (!setup) { + c = inbuf[0]; + setup++; + } + /* Test the packet read back for data pattern */ + loop_errorcount = 0; + for (x = 0; x < bs; x++) { + /* if error */ + if (inbuf[x] != c) { + total_errorcount++; + loop_errorcount++; + if (oldstyle_cmdline) { + printf("(Error %ld): Unexpected result, %d != %d, %ld bytes since last error.\n", total_errorcount, inbuf[x],c, bytes); + } else { + if (1 <= verbose) { + printf("Error %ld (loop %ld, offset %d, error %d): Unexpected result, Read: 0x%02x, Expected 0x%02x.\n", + total_errorcount, + currentloop, + x, + loop_errorcount, + inbuf[x], + c); + } + if (2 <= verbose) { + show_error_context(inbuf, x, bs); + } + } + /* Reset the expected data to what was just read. so test can resynch on skipped data */ + c = inbuf[x]; + bytes=0; /* Reset the count from the last encountered error */ + } + c++; + bytes++; + } + /* If the user wants to see some of each buffer transaction */ + if (0 < buff_disp) { + printf("Buffer Display %d (errors =%d)\nIN: ", buff_disp, loop_errorcount); + print_packet(inbuf, 64); + printf("OUT:"); + print_packet(outbuf, 64); + } + + currentloop++; + /* Update stats if the user has specified it */ + if (0 < reportloops && 0 == (currentloop % reportloops)) { + printf("Status on loop %lu: Total errors = %lu\n", currentloop, total_errorcount); + + } +#if 0 + printf("(%d) Wrote %d bytes\n", packets++, res); +#endif + if(timeout && (time(NULL)-start_time) > timeout){ + printf("Timeout achieved Ending Program\n"); + printf("Test ran %ld loops of %d bytes/loop with %ld errors\n", currentloop, bs, total_errorcount); + return total_errorcount; + } + } + +} + diff --git a/pattest.c b/pattest.c new file mode 100644 index 0000000..09b0c8e --- /dev/null +++ b/pattest.c @@ -0,0 +1,181 @@ +/* + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "bittest.h" + +#include +#include "dahdi_tools_version.h" + +#define BLOCK_SIZE 2039 +#define DEVICE "/dev/dahdi/channel" + +static const char rcsid[] = "$Id$"; +char *prog_name; + +static void usage(void) +{ + fprintf(stderr, "Usage: %s \n", prog_name); + fprintf(stderr, " e.g.: %s /dev/dahdi/55\n", prog_name); + fprintf(stderr, " %s 455\n", prog_name); + fprintf(stderr, "%s version %s\n", prog_name, rcsid); + exit(1); +} + +void print_packet(unsigned char *buf, int len) +{ + int x; + printf("{ "); + for (x=0;x 0) { + fd = open(DEVICE, O_RDWR, 0600); + if (fd < 0) { + perror(DEVICE); + return -1; + } + if (ioctl(fd, DAHDI_SPECIFY, &channo) < 0) { + perror("DAHDI_SPECIFY ioctl failed"); + return -1; + } + /* die */ + } else { + fprintf(stderr, "Specified channel is not a valid character " + "device or channel number"); + return -1; + } + + if (ioctl(fd, DAHDI_SET_BLOCKSIZE, bs) < 0) { + perror("SET_BLOCKSIZE"); + return -1; + } + + if (ioctl(fd, DAHDI_GET_PARAMS, &tp)) { + fprintf(stderr, "Unable to get channel parameters\n"); + return -1; + } + + return fd; +} + +int main(int argc, char *argv[]) +{ + int fd; + int res, x; + int bs = BLOCK_SIZE; + unsigned char c=0; + unsigned char outbuf[BLOCK_SIZE]; + int setup=0; + int errors=0; + int bytes=0; + + prog_name = argv[0]; + + if (argc < 2) { + usage(); + } + + fd = channel_open(argv[1], &bs); + if (fd < 0) + exit(1); + + ioctl(fd, DAHDI_GETEVENT); + for(;;) { + res = bs; + res = read(fd, outbuf, res); + if (res < bs) { + int e; + struct dahdi_spaninfo zi; + res = ioctl(fd,DAHDI_GETEVENT,&e); + if (res == -1) + { + perror("DAHDI_GETEVENT"); + exit(1); + } + if (e == DAHDI_EVENT_NOALARM) + printf("ALARMS CLEARED\n"); + if (e == DAHDI_EVENT_ALARM) + { + zi.spanno = 0; + res = ioctl(fd,DAHDI_SPANSTAT,&zi); + if (res == -1) + { + perror("DAHDI_SPANSTAT"); + exit(1); + } + printf("Alarm mask %x hex\n",zi.alarms); + } + continue; + } + if (!setup) { + c = outbuf[0]; + setup++; + } + for (x=0;x + * + * Borrows from PPPoE by Michal Ostrowski , + * Jamal Hadi Salim + * + * which in turn... + * + * Borrows heavily from the PPPoATM plugin by Mitchell Blank Jr., + * which is based in part on work from Jens Axboe and Paul Mackerras. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +extern int new_style_driver; + +const char pppd_version[] = VERSION; + +#define _PATH_DAHDI_OPT _ROOT_PATH "/etc/ppp/options." + +#define DAHDI_MTU (DAHDI_DEFAULT_MTU_MRU - 16) +extern int kill_link; +int retries = 0; + +int setdevname_dahdi(const char *cp); + +static option_t dahdi_options[] = { + { "device name", o_wild, (void *) &setdevname_dahdi, + "Serial port device name", + OPT_DEVNAM | OPT_PRIVFIX | OPT_NOARG | OPT_A2STRVAL | OPT_STATIC, + devnam}, + { NULL } +}; + +static int dahdi_fd = -1; +static int dahdi_chan = 0; + +static int connect_dahdi(void) +{ + + struct dahdi_params dahdi_params; + int res; + int x; + + info("DAHDI device is '%s'\n", devnam); + + strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam)); + + if (strlen(devnam) && strcmp(devnam, "stdin")) { + /* Get the channel number */ + dahdi_chan = atoi(devnam); + if (dahdi_chan < 1) { + fatal("'%s' is not a valid device name\n", devnam); + return -1; + } + + /* Open /dev/dahdi/channel interface */ + dahdi_fd = open("/dev/dahdi/channel", O_RDWR); + if (dahdi_fd < 0) { + fatal("Unable to open DAHDI channel interface: '%s'\n", strerror(errno)); + return dahdi_fd; + } + + /* Specify which channel we really want */ + x = dahdi_chan; + res = ioctl(dahdi_fd, DAHDI_SPECIFY, &x); + if (res) { + fatal("Unable to specify channel %d: %s\n", dahdi_chan, strerror(errno)); + close(dahdi_fd); + dahdi_fd = -1; + return -1; + } + } else + dahdi_fd = STDIN_FILENO; + + + /* Get channel parameters */ + memset(&dahdi_params, 0, sizeof(dahdi_params)); + dahdi_params.channo = -1; + + res = ioctl(dahdi_fd, DAHDI_GET_PARAMS, &dahdi_params); + + if (res) { + fatal("Device '%s' does not appear to be a DAHDI device\n", devnam ? devnam : ""); + } + + x = 1; + + /* Throw into HDLC/PPP mode */ + res = ioctl(dahdi_fd, DAHDI_HDLCPPP, &x); + + if (res) { + fatal("Unable to put device '%s' into HDLC mode\n", devnam); + close(dahdi_fd); + dahdi_fd = -1; + return -1; + } + + /* Once the logging is fixed, print a message here indicating + connection parameters */ + dahdi_chan = dahdi_params.channo; + info("Connected to DAHDI device '%s' (%d)\n", dahdi_params.name, dahdi_params.channo); + + return dahdi_fd; +} + +static void disconnect_dahdi(void) +{ + int res; + int x = 0; + /* Throw out of HDLC mode */ + res = ioctl(dahdi_fd, DAHDI_HDLCPPP, &x); + + if (res) { + warn("Unable to take device '%s' out of HDLC mode\n", devnam); + } + + /* Close if it's not stdin */ + if (strlen(devnam)) + close(dahdi_fd); + warn("Disconnect from DAHDI"); + +} + + +static int setspeed_dahdi(const char *cp) +{ + return 0; +} + +static void dahdi_extra_options() +{ + int ret; + char buf[256]; + snprintf(buf, 256, _PATH_DAHDI_OPT "%s",devnam); + if(!options_from_file(buf, 0, 0, 1)) + exit(EXIT_OPTION_ERROR); + +} + + + +static void send_config_dahdi(int mtu, + u_int32_t asyncmap, + int pcomp, + int accomp) +{ + int sock; + + if (mtu > DAHDI_MTU) { + warn("Couldn't increase MTU to %d.", mtu); + mtu = DAHDI_MTU; + } +} + + +static void recv_config_dahdi(int mru, + u_int32_t asyncmap, + int pcomp, + int accomp) +{ + if (mru > DAHDI_MTU) + error("Couldn't increase MRU to %d", mru); +} + +static void set_xaccm_pppoe(int unit, ext_accm accm) +{ + /* NOTHING */ +} + + + +struct channel dahdi_channel; + +/* Check is cp is a valid DAHDI device + * return either 1 if "cp" is a reasonable thing to name a device + * or die. + * Note that we don't actually open the device at this point + * We do need to fill in: + * devnam: a string representation of the device + */ + +int (*old_setdevname_hook)(const char* cp) = NULL; +int setdevname_dahdi(const char *cp) +{ + int ret; + int chan; + + /* If already set, forgoe */ + if (strlen(devnam)) + return 1; + + + if (strcmp(cp, "stdin")) { + ret = sscanf(cp, "%d", &chan); + if (ret != 1) { + fatal("DAHDI: Invalid channel: '%s'\n", cp); + return -1; + } + } + + dahdi_copy_string(devnam, cp, sizeof(devnam)); + + info("Using DAHDI device '%s'\n", devnam); + + ret = 1; + + if( ret == 1 && the_channel != &dahdi_channel ){ + + the_channel = &dahdi_channel; + + modem = 0; + + lcp_allowoptions[0].neg_accompression = 0; + lcp_wantoptions[0].neg_accompression = 0; + + lcp_allowoptions[0].neg_pcompression = 0; + lcp_wantoptions[0].neg_pcompression = 0; + + ccp_allowoptions[0].deflate = 0 ; + ccp_wantoptions[0].deflate = 0 ; + + ipcp_allowoptions[0].neg_vj=0; + ipcp_wantoptions[0].neg_vj=0; + + ccp_allowoptions[0].bsd_compress = 0; + ccp_wantoptions[0].bsd_compress = 0; + + lcp_allowoptions[0].neg_asyncmap = 0; + lcp_wantoptions[0].neg_asyncmap = 0; + + } + return ret; +} + + + +void plugin_init(void) +{ + if (!ppp_available() && !new_style_driver) + fatal("Kernel doesn't support ppp_generic needed for DAHDI PPP"); + add_options(dahdi_options); + + info("DAHDI Plugin Initialized"); +} + +struct channel dahdi_channel = { + options: dahdi_options, + process_extra_options: &dahdi_extra_options, + check_options: NULL, + connect: &connect_dahdi, + disconnect: &disconnect_dahdi, + establish_ppp: &generic_establish_ppp, + disestablish_ppp: &generic_disestablish_ppp, + send_config: &send_config_dahdi, + recv_config: &recv_config_dahdi, + close: NULL, + cleanup: NULL +}; + diff --git a/sethdlc.c b/sethdlc.c new file mode 100644 index 0000000..cc0517c --- /dev/null +++ b/sethdlc.c @@ -0,0 +1,704 @@ +/* + * sethdlc.c + * + * Copyright (C) 1999 - 2002 Krzysztof Halasa + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "dahdi_tools_version.h" + +#if GENERIC_HDLC_VERSION != 4 +#error Generic HDLC layer version mismatch, please get correct sethdlc.c +#endif + +#if !defined(IF_PROTO_HDLC_ETH) || !defined(IF_PROTO_FR_ETH_PVC) +#warning "No kernel support for Ethernet over Frame Relay / HDLC, skipping it" +#endif + + +static struct ifreq req; /* for ioctl */ +static int argc; +static char **argv; +int sock; + + +static void error(const char *format, ...) __attribute__ ((noreturn, format(printf, 1, 2))); + +static void error(const char *format, ...) +{ + va_list args; + + va_start(args, format); + fprintf(stderr, "%s: ", req.ifr_name); + vfprintf(stderr, format, args); + va_end(args); + exit(1); +} + + + +typedef struct { + const char *name; + const unsigned int value; +} parsertab; + + + +static int checkkey(const char* name) +{ + if (argc < 1) + return -1; /* no enough parameters */ + + if (strcmp(name, argv[0])) + return -1; + argc--; + argv++; + return 0; +} + + + +static int checktab(parsertab *tab, unsigned int *value) +{ + int i; + + if (argc < 1) + return -1; /* no enough parameters */ + + for (i = 0; tab[i].name; i++) + if (!strcmp(tab[i].name, argv[0])) { + argc--; + argv++; + *value = tab[i].value; + return 0; + } + + return -1; /* Not found */ +} + + + +static const char* tabstr(unsigned int value, parsertab *tab, + const char* unknown) +{ + int i; + for (i = 0; tab[i].name; i++) + if (tab[i].value == value) + return tab[i].name; + + return unknown; /* Not found */ +} + + + +static unsigned int match(const char* name, unsigned int *value, + unsigned int minimum, unsigned int maximum) +{ + char test; + + if (argc < 1) + return -1; /* no enough parameters */ + + if (name) { + if (strcmp(name, argv[0])) + return -1; + argc--; + argv++; + } + + if (argc < 1) + error("Missing parameter\n"); + + if (sscanf(argv[0], "%u%c", value, &test) != 1) + error("Invalid parameter: %s\n", argv[0]); + + if ((*value > maximum) || (*value < minimum)) + error("Parameter out of range [%u - %u]: %u\n", + minimum, maximum, *value); + + argc--; + argv++; + return 0; +} + + +static parsertab ifaces[] = {{ "v35", IF_IFACE_V35 }, + { "v24", IF_IFACE_V24 }, + { "x21", IF_IFACE_X21 }, + { "e1", IF_IFACE_E1 }, + { "t1", IF_IFACE_T1 }, + { NULL, 0 }}; + +static parsertab clocks[] = {{ "int", CLOCK_INT }, + { "ext", CLOCK_EXT }, + { "txint", CLOCK_TXINT }, + { "txfromrx", CLOCK_TXFROMRX }, + { NULL, 0 }}; + + +static parsertab protos[] = {{ "hdlc", IF_PROTO_HDLC}, + { "cisco", IF_PROTO_CISCO}, + { "fr", IF_PROTO_FR}, + { "ppp", IF_PROTO_PPP}, + { "x25", IF_PROTO_X25}, +#ifdef IF_PROTO_HDLC_ETH + { "hdlc-eth", IF_PROTO_HDLC_ETH}, +#endif + { NULL, 0 }}; + + +static parsertab hdlc_enc[] = {{ "nrz", ENCODING_NRZ }, + { "nrzi", ENCODING_NRZI }, + { "fm-mark", ENCODING_FM_MARK }, + { "fm-space", ENCODING_FM_SPACE }, + { "manchester", ENCODING_MANCHESTER }, + { NULL, 0 }}; + +static parsertab hdlc_par[] = {{ "no-parity", PARITY_NONE }, + { "crc16", PARITY_CRC16_PR1 }, + { "crc16-pr0", PARITY_CRC16_PR0 }, + { "crc16-itu", PARITY_CRC16_PR1_CCITT }, + { "crc16-itu-pr0", PARITY_CRC16_PR0_CCITT }, + { "crc32-itu", PARITY_CRC32_PR1_CCITT }, + { NULL, 0 }}; + +static parsertab lmi[] = {{ "none", LMI_NONE }, + { "ansi", LMI_ANSI }, + { "ccitt", LMI_CCITT }, + { NULL, 0 }}; + + +static void set_iface(void) +{ + int orig_argc = argc; + te1_settings te1; + + memset(&te1, 0, sizeof(te1)); + req.ifr_settings.type = IF_IFACE_SYNC_SERIAL; + + while (argc > 0) { + if (req.ifr_settings.type == IF_IFACE_SYNC_SERIAL) + if (!checktab(ifaces, &req.ifr_settings.type)) + continue; + + if (!te1.clock_type) + if (!checkkey("clock")) { + if (!checktab(clocks, &te1.clock_type)) + continue; + error("Invalid clock type\n"); + } + + if (!te1.clock_rate && + (te1.clock_type == CLOCK_INT || + te1.clock_type == CLOCK_TXINT)) + if (!match("rate", &te1.clock_rate, 1, 0xFFFFFFFF)) + continue; + if (!te1.loopback) { + if (!checkkey("loopback") || + !checkkey("lb")) { + te1.loopback = 1; + continue; + } + } + /* slotmap goes here */ + + if (orig_argc == argc) + return; /* not an iface definition */ + error("Invalid parameter: %s\n", argv[0]); + } + + if (!te1.clock_rate && + (te1.clock_type == CLOCK_INT || + te1.clock_type == CLOCK_TXINT)) + te1.clock_rate = 64000; + + /* FIXME stupid hack, will remove it later */ + req.ifr_settings.ifs_ifsu.te1 = &te1; + if (req.ifr_settings.type == IF_IFACE_E1 || + req.ifr_settings.type == IF_IFACE_T1) + req.ifr_settings.size = sizeof(te1_settings); + else + req.ifr_settings.size = sizeof(sync_serial_settings); + + if (ioctl(sock, SIOCWANDEV, &req)) + error("Unable to set interface information: %s\n", + strerror(errno)); + + exit(0); +} + + + +static void set_proto_fr(void) +{ + unsigned int lmi_type = 0; + fr_proto fr; + + memset(&fr, 0, sizeof(fr)); + + while (argc > 0) { + if (!lmi_type) + if (!checkkey("lmi")) { + if (!checktab(lmi, &lmi_type)) + continue; + error("Invalid LMI type: %s\n", + argv[0]); + } + + if (lmi_type && lmi_type != LMI_NONE) { + if (!fr.dce) + if (!checkkey("dce")) { + fr.dce = 1; + continue; + } + + if (!fr.t391) + if (!match("t391", &fr.t391, + 1, 1000)) + continue; + if (!fr.t392) + if (!match("t392", &fr.t392, + 1, 1000)) + continue; + if (!fr.n391) + if (!match("n391", &fr.n391, + 1, 1000)) + continue; + if (!fr.n392) + if (!match("n392", &fr.n392, + 1, 1000)) + continue; + if (!fr.n393) + if (!match("n393", &fr.n393, + 1, 1000)) + continue; + } + error("Invalid parameter: %s\n", argv[0]); + } + + /* polling verification timer*/ + if (!fr.t391) fr.t391 = 10; + /* link integrity verification polling timer */ + if (!fr.t392) fr.t392 = 15; + /* full status polling counter*/ + if (!fr.n391) fr.n391 = 6; + /* error threshold */ + if (!fr.n392) fr.n392 = 3; + /* monitored events count */ + if (!fr.n393) fr.n393 = 4; + + if (!lmi_type) + fr.lmi = LMI_DEFAULT; + else + fr.lmi = lmi_type; + + req.ifr_settings.ifs_ifsu.fr = &fr; + req.ifr_settings.size = sizeof(fr); + + if (ioctl(sock, SIOCWANDEV, &req)) + error("Unable to set FR protocol information: %s\n", + strerror(errno)); +} + + + +static void set_proto_hdlc(int eth) +{ + unsigned int enc = 0, par = 0; + raw_hdlc_proto raw; + + memset(&raw, 0, sizeof(raw)); + + while (argc > 0) { + if (!enc) + if (!checktab(hdlc_enc, &enc)) + continue; + if (!par) + if (!checktab(hdlc_par, &par)) + continue; + + error("Invalid parameter: %s\n", argv[0]); + } + + if (!enc) + raw.encoding = ENCODING_DEFAULT; + else + raw.encoding = enc; + + if (!par) + raw.parity = ENCODING_DEFAULT; + else + raw.parity = par; + + req.ifr_settings.ifs_ifsu.raw_hdlc = &raw; + req.ifr_settings.size = sizeof(raw); + + if (ioctl(sock, SIOCWANDEV, &req)) + error("Unable to set HDLC%s protocol information: %s\n", + eth ? "-ETH" : "", strerror(errno)); +} + + + +static void set_proto_cisco(void) +{ + cisco_proto cisco; + memset(&cisco, 0, sizeof(cisco)); + + while (argc > 0) { + if (!cisco.interval) + if (!match("interval", &cisco.interval, + 1, 100)) + continue; + if (!cisco.timeout) + if (!match("timeout", &cisco.timeout, + 1, 100)) + continue; + + error("Invalid parameter: %s\n", + argv[0]); + } + + if (!cisco.interval) + cisco.interval = 10; + if (!cisco.timeout) + cisco.timeout = 25; + + req.ifr_settings.ifs_ifsu.cisco = &cisco; + req.ifr_settings.size = sizeof(cisco); + + if (ioctl(sock, SIOCWANDEV, &req)) + error("Unable to set Cisco HDLC protocol information: %s\n", + strerror(errno)); +} + + + +static void set_proto(void) +{ + if (checktab(protos, &req.ifr_settings.type)) + return; + + switch(req.ifr_settings.type) { + case IF_PROTO_HDLC: set_proto_hdlc(0); break; +#ifdef IF_PROTO_HDLC_ETH + case IF_PROTO_HDLC_ETH: set_proto_hdlc(1); break; +#endif + case IF_PROTO_CISCO: set_proto_cisco(); break; + case IF_PROTO_FR: set_proto_fr(); break; + + case IF_PROTO_PPP: + case IF_PROTO_X25: + req.ifr_settings.ifs_ifsu.sync = NULL; /* FIXME */ + req.ifr_settings.size = 0; + + if (!ioctl(sock, SIOCWANDEV, &req)) + break; + + error("Unable to set %s protocol information: %s\n", + req.ifr_settings.type == IF_PROTO_PPP + ? "PPP" : "X.25", strerror(errno)); + + default: error("Unknown protocol %u\n", req.ifr_settings.type); + } + + if (argc > 0) + error("Unexpected parameter: %s\n", argv[0]); + + close(sock); + exit(0); +} + + + +static void set_pvc(void) +{ + char *op = argv[0]; + parsertab ops[] = {{ "create", IF_PROTO_FR_ADD_PVC }, + { "delete", IF_PROTO_FR_DEL_PVC }, + { NULL, 0 }}; + fr_proto_pvc pvc; + + memset(&pvc, 0, sizeof(pvc)); + + if (checktab(ops, &req.ifr_settings.type)) + return; + +#ifdef IF_PROTO_FR_ETH_PVC + if (!match("ether", &pvc.dlci, 0, 1023)) { + if (req.ifr_settings.type == IF_PROTO_FR_ADD_PVC) + req.ifr_settings.type = IF_PROTO_FR_ADD_ETH_PVC; + else + req.ifr_settings.type = IF_PROTO_FR_DEL_ETH_PVC; + + } else +#endif + if (match(NULL, &pvc.dlci, 0, 1023)) + return; + + if (argc != 0) + return; + + req.ifr_settings.ifs_ifsu.fr_pvc = &pvc; + req.ifr_settings.size = sizeof(pvc); + + if (ioctl(sock, SIOCWANDEV, &req)) + error("Unable to %s PVC: %s\n", op, strerror(errno)); + exit(0); +} + + + +static void private(void) +{ + if (argc < 1) + return; + + if (!strcmp(argv[0], "private")) { + if (argc != 1) + return; + if (ioctl(sock, SIOCDEVPRIVATE, &req)) + error("SIOCDEVPRIVATE: %s\n", strerror(errno)); + exit(0); + } +} + + + +static void show_port(void) +{ + const char *s; + char buffer[128]; + const te1_settings *te1 = (void*)buffer; + const raw_hdlc_proto *raw = (void*)buffer; + const cisco_proto *cisco = (void*)buffer; + const fr_proto *fr = (void*)buffer; +#ifdef IF_PROTO_FR_PVC + const fr_proto_pvc_info *pvc = (void*)buffer; +#endif + req.ifr_settings.ifs_ifsu.sync = (void*)buffer; /* FIXME */ + + printf("%s: ", req.ifr_name); + + req.ifr_settings.size = sizeof(buffer); + req.ifr_settings.type = IF_GET_IFACE; + + if (ioctl(sock, SIOCWANDEV, &req)) + if (errno != EINVAL) { + printf("unable to get interface information: %s\n", + strerror(errno)); + close(sock); + exit(1); + } + + /* Get and print physical interface settings */ + if (req.ifr_settings.type == IF_IFACE_SYNC_SERIAL) + s = ""; /* Unspecified serial interface */ + else + s = tabstr(req.ifr_settings.type, ifaces, NULL); + + if (!s) + printf("unknown interface 0x%x\n", req.ifr_settings.type); + else { + if (*s) + printf("interface %s ", s); + + printf("clock %s", tabstr(te1->clock_type, clocks, + "type unknown")); + if (te1->clock_type == CLOCK_INT || + te1->clock_type == CLOCK_TXINT) + printf(" rate %u", te1->clock_rate); + + if (te1->loopback) + printf(" loopback"); + + if (req.ifr_settings.type == IF_IFACE_E1 || + req.ifr_settings.type == IF_IFACE_T1) { + unsigned int u; + printf(" slotmap "); + for (u = te1->slot_map; u != 0; u /= 2) + printf("%u", u % 2); + } + printf("\n"); + } + + /* Get and print protocol settings */ + do { + printf("\t"); + req.ifr_settings.size = sizeof(buffer); + req.ifr_settings.type = IF_GET_PROTO; + + if (ioctl(sock, SIOCWANDEV, &req)) { + if (errno == EINVAL) + printf("no protocol set\n"); + else + printf("unable to get protocol information: " + "%s\n", strerror(errno)); + break; + } + + switch(req.ifr_settings.type) { + case IF_PROTO_FR: + printf("protocol fr lmi %s", + tabstr(fr->lmi, lmi, "unknown")); + if (fr->lmi == LMI_ANSI || + fr->lmi == LMI_CCITT) + printf("%s t391 %u t392 %u n391 %u n392 %u " + "n393 %u\n", + fr->dce ? " dce" : "", + fr->t391, + fr->t392, + fr->n391, + fr->n392, + fr->n393); + else + putchar('\n'); + break; + +#ifdef IF_PROTO_FR_PVC + case IF_PROTO_FR_PVC: + printf("Frame-Relay PVC: DLCI %u, master device %s\n", + pvc->dlci, pvc->master); + break; +#endif + +#ifdef IF_PROTO_FR_ETH_PVC + case IF_PROTO_FR_ETH_PVC: + printf("Frame-Relay PVC (Ethernet emulation): DLCI %u," + " master device %s\n", pvc->dlci, pvc->master); + break; +#endif + + case IF_PROTO_HDLC: + printf("protocol hdlc %s %s\n", + tabstr(raw->encoding, hdlc_enc, "unknown"), + tabstr(raw->parity, hdlc_par, "unknown")); + break; + +#ifdef IF_PROTO_HDLC_ETH + case IF_PROTO_HDLC_ETH: + printf("protocol hdlc-eth %s %s\n", + tabstr(raw->encoding, hdlc_enc, "unknown"), + tabstr(raw->parity, hdlc_par, "unknown")); + break; +#endif + + case IF_PROTO_CISCO: + printf("protocol cisco interval %u timeout %u\n", + cisco->interval, + cisco->timeout); + break; + + case IF_PROTO_PPP: + printf("protocol ppp\n"); + break; + + case IF_PROTO_X25: + printf("protocol x25\n"); + break; + + default: + printf("unknown protocol %u\n", req.ifr_settings.type); + } + }while(0); + + close(sock); + exit(0); +} + + + +static void usage(void) +{ + fprintf(stderr, "sethdlc version 1.15\n" + "Copyright (C) 2000 - 2003 Krzysztof Halasa \n" + "\n" + "Usage: sethdlc INTERFACE [PHYSICAL] [clock CLOCK] [LOOPBACK] " + "[slotmap SLOTMAP]\n" + " sethdlc INTERFACE [PROTOCOL]\n" + " sethdlc INTERFACE create | delete" +#ifdef IF_PROTO_FR_ETH_PVC + " [ether]" +#endif + " DLCI\n" + " sethdlc INTERFACE private...\n" + "\n" + "PHYSICAL := v24 | v35 | x21 | e1 | t1\n" + "CLOCK := int [rate RATE] | ext | txint [rate RATE] | txfromrx\n" + "LOOPBACK := loopback | lb\n" + "\n" + "PROTOCOL := hdlc [ENCODING] [PARITY] |\n" +#ifdef IF_PROTO_HDLC_ETH + " hdlc-eth [ENCODING] [PARITY] |\n" +#endif + " cisco [interval val] [timeout val] |\n" + " fr [lmi LMI] |\n" + " ppp |\n" + " x25\n" + "\n" + "ENCODING := nrz | nrzi | fm-mark | fm-space | manchester\n" + "PARITY := no-parity | crc16 | crc16-pr0 | crc16-itu | crc16-itu-pr0 | crc32-itu\n" + "LMI := none | ansi [LMI_SPEC] | ccitt [LMI_SPEC]\n" + "LMI_SPEC := [dce] [t391 val] [t392 val] [n391 val] [n392 val] [n393 val]\n"); + exit(0); +} + + + +int main(int arg_c, char *arg_v[]) +{ + argc = arg_c; + argv = arg_v; + + if (argc <= 1) + usage(); + + sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); + if (sock < 0) + error("Unable to create socket: %s\n", strerror(errno)); + + dahdi_copy_string(req.ifr_name, argv[1], sizeof(req.ifr_name)); /* Device name */ + + if (argc == 2) + show_port(); + + argc -= 2; + argv += 2; + + set_iface(); + set_proto(); + set_pvc(); + private(); + + close(sock); + usage(); + exit(0); +} diff --git a/span-types.conf.sample b/span-types.conf.sample new file mode 100644 index 0000000..71c391e --- /dev/null +++ b/span-types.conf.sample @@ -0,0 +1,28 @@ +# +# /etc/dahdi/spantype.conf: Set E1/T1/J1 per-device +# +# Built as a table of two columns: +# : +# +# Where: +# * The field may be either: +# hardware_id +# @location +# devpath (in sysfs) +# * The is the relative span number +# in the device (starting from 1) +# In this filed globbing rules apply. E.g: +# - * are all the spans in this device +# - [12] are the first two spans in this device +# * The may be E1, T1 or J1 +# +# Examples: +# Set the first two spans of a specific Astribank to T1 +#usb:000156 [12]:T1 + +# Set all spans of another Astribank to T1 +#usb:INT03165 *:E1 + +# Set the first two spans of an Astribank to T1. The +# Astribanks is specified by its location instead of hardware_id +#@usb-0000:00:1d.7-3 [12]:T1 diff --git a/system.conf.sample b/system.conf.sample new file mode 100644 index 0000000..f05ecb8 --- /dev/null +++ b/system.conf.sample @@ -0,0 +1,326 @@ +# +# DAHDI Configuration File +# +# This file is parsed by the DAHDI Configurator, dahdi_cfg +# +# Span Configuration +# ++++++++++++++++++ +# First come the span definitions, in the format +# +# span=,,,,[,yellow] +# +# All T1/E1/BRI spans generate a clock signal on their transmit side. The +# parameter determines whether the clock signal from the far +# end of the T1/E1/BRI is used as the master source of clock timing. If it is, our +# own clock will synchronise to it. T1/E1/BRI connected directly or indirectly to +# a PSTN provider (telco) should generally be the first choice to sync to. The +# PSTN will never be a slave to you. You must be a slave to it. +# +# Choose 1 to make the equipment at the far end of the E1/T1/BRI link the preferred +# source of the master clock. Choose 2 to make it the second choice for the master +# clock, if the first choice port fails (the far end dies, a cable breaks, or +# whatever). Choose 3 to make a port the third choice, and so on. If you have, say, +# 2 ports connected to the PSTN, mark those as 1 and 2. The number used for each +# port should be different. +# +# If you choose 0, the port will never be used as a source of timing. This is +# appropriate when you know the far end should always be a slave to you. If +# the port is connected to a channel bank, for example, you should always be +# its master. Likewise, BRI TE ports should always be configured as a slave. +# Any number of ports can be marked as 0. +# +# Incorrect timing sync may cause clicks/noise in the audio, poor quality or failed +# faxes, unreliable modem operation, and is a general all round bad thing. +# +# NOTE: The B410P card cannot reliably connect one of its four ports +# configured in TE mode to another one configured in NT mode. It will not +# reliably sync clock from itself. Please use another physical card and +# configure one to provide clock and one to recover clock in any B410P test +# environments. +# +# The line build-out (or LBO) is an integer, from the following table: +# +# 0: 0 db (CSU) / 0-133 feet (DSX-1) +# 1: 133-266 feet (DSX-1) +# 2: 266-399 feet (DSX-1) +# 3: 399-533 feet (DSX-1) +# 4: 533-655 feet (DSX-1) +# 5: -7.5db (CSU) +# 6: -15db (CSU) +# 7: -22.5db (CSU) +# +# If the span is a BRI port the line build-out is not used and should be set +# to 0. +# +# framing:: +# one of 'd4' or 'esf' for T1 or 'cas' or 'ccs' for E1. Use 'ccs' for BRI. +# 'd4' could be referred to as 'sf' or 'superframe' +# +# coding:: +# one of 'ami' or 'b8zs' for T1 or 'ami' or 'hdb3' for E1. Use 'ami' for +# BRI. +# +# * For E1 there is the optional keyword 'crc4' to enable CRC4 checking. +# * If the keyword 'yellow' follows, yellow alarm is transmitted when no +# channels are open. +# +#span=1,0,0,esf,b8zs +#span=2,1,0,esf,b8zs +#span=3,0,0,ccs,hdb3,crc4 +# +# Dynamic Spans +# +++++++++++++ +# Next come the dynamic span definitions, in the form: +# +# dynamic=,
,, +# +# Where is the name of the driver (e.g. eth),
is the +# driver specific address (like a MAC for eth), is the number +# of channels, and is a timing priority, like for a normal span. +# use "0" to not use this as a timing source, or prioritize them as +# primary, secondard, etc. Note that you MUST have a REAL DAHDI device +# if you are not using external timing. +# +# dynamic=eth,eth0/00:02:b3:35:43:9c,24,0 +# +# If a non-zero timing value is used, as above, only the last span should +# have the non-zero value. +# +# Channel Configuration +# +++++++++++++++++++++ +# Next come the definitions for using the channels. The format is: +# = +# +# Valid devices are: +# +# e&m:: +# Channel(s) are signalled using E&M signalling on a T1 line. +# Specific implementation, such as Immediate, Wink, or Feature +# Group D are handled by the userspace library. +# e&me1:: +# Channel(s) are signalled using E&M signalling on an E1 line. +# fxsls:: +# Channel(s) are signalled using FXS Loopstart protocol. +# fxsgs:: +# Channel(s) are signalled using FXS Groundstart protocol. +# fxsks:: +# Channel(s) are signalled using FXS Koolstart protocol. +# fxols:: +# Channel(s) are signalled using FXO Loopstart protocol. +# fxogs:: +# Channel(s) are signalled using FXO Groundstart protocol. +# fxoks:: +# Channel(s) are signalled using FXO Koolstart protocol. +# +# unused:: +# No signalling is performed, each channel in the list remains idle +# clear:: +# Channel(s) are bundled into a single span. No conversion or +# signalling is performed, and raw data is available on the master. +# bchan:: +# Like 'clear' except all channels are treated individually and +# are not bundled. 'inclear' is an alias for this. +# rawhdlc:: +# The DAHDI driver performs HDLC encoding and decoding on the +# bundle, and the resulting data is communicated via the master +# device. +# dchan:: +# The DAHDI driver performs HDLC encoding and decoding on the +# bundle and also performs incoming and outgoing FCS insertion +# and verification. 'fcshdlc' is an alias for this. +# hardhdlc:: +# The hardware driver performs HDLC encoding and decoding on the +# bundle and also performs incoming and outgoing FCS insertion +# and verification. Is subject to limitations and support of underlying +# hardware. BRI spans serviced by the wcb4xxp driver must use hardhdlc +# channels for the signalling channels. +# nethdlc:: +# The DAHDI driver bundles the channels together into an +# hdlc network device, which in turn can be configured with +# sethdlc (available separately). In 2.6.x kernels you can also optionally +# pass the name for the network interface after the channel list. +# Syntax: +# +# nethdlc=[:interface name] +# Use original names, don't use the names which have been already registered +# in system e.g eth. +# +# dacs:: +# The DAHDI driver cross connects the channels starting at +# the channel number listed at the end, after a colon +# dacsrbs:: +# The DAHDI driver cross connects the channels starting at +# the channel number listed at the end, after a colon and +# also performs the DACSing of RBS bits +# +# The channel list is a comma-separated list of channels or ranges, for +# example: +# +# 1,3,5 (channels one, three, and five) +# 16-23, 29 (channels 16 through 23, as well as channel 29) +# +# So, some complete examples are: +# +# e&m=1-12 +# nethdlc=13-24 +# fxsls=25,26,27,28 +# fxols=29-32 +# +# An example of BRI port: +# +# span=1,1,0,ccs,ami +# bchan=1,2 +# hardhdlc=3 +# +# NOTE: When using BRI channels in asterisk, use the bri_cpe, bri_net, or +# bri_cpe_ptmp (for point to multipoint mode). libpri does not currently +# support point to multipoint when in NT mode. Otherwise, the bearer channel +# are configured identically to other DAHDI channels. +# +#fxoks=1-24 +#bchan=25-47 +#dchan=48 +#fxols=1-12 +#fxols=13-24 +#e&m=25-29 +#nethdlc=30-33 +#clear=44 +#clear=45 +#clear=46 +#clear=47 +#fcshdlc=48 +#dacs=1-24:48 +#dacsrbs=1-24:48 +# +# Tone Zone Data +# ++++++++++++++ +# Finally, you can preload some tone zones, to prevent them from getting +# overwritten by other users (if you allow non-root users to open /dev/dahdi/* +# interfaces anyway. Also this means they won't have to be loaded at runtime. +# The format is "loadzone=" where the zone is a two letter country code. +# +# You may also specify a default zone with "defaultzone=" where zone +# is a two letter country code. +# +# An up-to-date list of the zones can be found in the file zonedata.c +# +loadzone = us +#loadzone = us-old +#loadzone=gr +#loadzone=it +#loadzone=fr +#loadzone=de +#loadzone=uk +#loadzone=fi +#loadzone=jp +#loadzone=sp +#loadzone=no +#loadzone=hu +#loadzone=lt +#loadzone=pl +defaultzone=us +# +# PCI Radio Interface +# +++++++++++++++++++ +# (see http://www.zapatatelephony.org/app_rpt.html) +# +# The PCI Radio Interface card interfaces up to 4 two-way radios (either +# a base/mobile radio or repeater system) to DAHDI channels. The driver +# may work either independent of an application, or with it, through +# the driver;s ioctl() interface. This file gives you access to specify +# load-time parameters for Radio channels, so that the driver may run +# by itself, and just act like a generic DAHDI radio interface. +# +# Unlike the rest of this file, you specify a block of parameters, and +# then the channel(s) to which they apply. CTCSS is specified as a frequency +# in tenths of hertz, for example 131.8 HZ is specified as 1318. DCS +# for receive is specified as the code directly, for example 223. DCS for +# transmit is specified as D and then the code, for example D223. +# +# The hardware supports a "community" CTCSS decoder system that has +# arbitrary transmit CTCSS or DCS codes associated with them, unlike +# traditional "community" systems that encode the same tone they decode. +# +# this example is a single tone DCS transmit and receive +# +# specify the transmit tone (in DCS mode this stays constant): +#tx=D371 +# +# specify the receive DCS code: +#dcsrx=223 +# +# this example is a "community" CTCSS (if you only want a single tone, then +# only specify 1 in the ctcss list) +# +# specify the default transmit tone (when not receiving): +#tx=1000 +# +# Specify the receive freq, the tag (use 0 if none), and the transmit code. +# The tag may be used by applications to determine classification of tones. +# The tones are to be specified in order of presedence, most important first. +# Currently, 15 tones may be specified.. +# +#ctcss=1318,1,1318 +#ctcss=1862,1,1862 +# +# The following parameters may be omitted if their default value is acceptible +# +# Set the receive debounce time in milliseconds: +#debouncetime=123 +# +# set the transmit quiet dropoff burst time in milliseconds: +#bursttime=234 +# +# set the COR level threshold (specified in tenths of millivolts) +# valid values are {3125,6250,9375,12500,15625,18750,21875,25000} +#corthresh=12500 +# +# Invert COR signal {y,n} +#invertcor=y +# Set the external tone mode; yes, no, internal {y,n,i} +#exttone=y +# +# Now apply the configuration to the specified channels: +# +# We are all done with our channel parameters, so now we specify what +# channels they apply to +#channels=1-4 +# +# Overiding PCM encoding +# ++++++++++++++++++++++ +# Usually the channel driver sets the encoding of the PCM for the +# channel (mulaw / alaw. That is: g711u or g711a). However there are +# some cases where you would like to override that. 'mulaw' and 'alaw' +# set different such encoding. Use them for channels you have already +# defined with e.g. 'bchan' or 'fxoks'. +#mulaw=1-4 +#alaw=1-4 +# +# 'deflaw' is similar, but resets the encoding to the channel driver's +# default. It must be useful for something, I guess. +#mulaw=1-10 +#deflaw=5 +# +# Echo Cancellers +# +++++++++++++++ +# DAHDI uses modular echo cancellers that are configured per channel. The echo +# cancellers are compiled and installed as part of the dahdi-linux package. +# You can specify in this file the echo canceller to be used for each +# channel. The default behavior is for there to be NO echo canceller on any +# channel, so it is very important that you specify one here. +# +# Valid echo cancellers are: hwec, mg2, kb1, sec2, and sec. +# 'hwec' is a special echo canceller that should be used if hardware echo +# cancellation is desired on and available on the specified channels. +# If compiled, 'hpec' is also a valid echo canceller. +# +# To configure the default echo cancellers, use the format: +# echocanceller=, +# +# Example: +# Configure channels 1 through 8 to use the mg2 echo canceller +#echocanceller=mg2,1-8 +# +# And change channel 2 to use the kb1 echo canceller. +#echocanceller=kb1,2 +# diff --git a/timertest.c b/timertest.c new file mode 100644 index 0000000..6f72885 --- /dev/null +++ b/timertest.c @@ -0,0 +1,78 @@ +/* + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "dahdi_tools_version.h" + +int main(int argc, char *argv[]) +{ + int fd; + int x = 8000; + int res; + fd_set fds; + struct timeval orig, now; + fd = open("/dev/dahdi/timer", O_RDWR); + if (fd < 0) { + fprintf(stderr, "Unable to open timer: %s\n", strerror(errno)); + exit(1); + } + printf("Opened timer...\n"); + if (ioctl(fd, DAHDI_TIMERCONFIG, &x)) { + fprintf(stderr, "Unable to set timer: %s\n", strerror(errno)); + exit(1); + } + printf("Set timer duration to %d samples (%d ms)\n", x, x/8); + printf("Waiting...\n"); + gettimeofday(&orig, NULL); + for(;;) { + FD_ZERO(&fds); + FD_SET(fd, &fds); + res = select(fd + 1, NULL, NULL, &fds, NULL); + if (res != 1) { + fprintf(stderr, "Unexpected result %d: %s\n", res, strerror(errno)); + exit(1); + } + x = -1; + if (ioctl(fd, DAHDI_TIMERACK, &x)) { + fprintf(stderr, "Unable to ack timer: %s\n", strerror(errno)); + exit(1); + } + gettimeofday(&now, NULL); + printf("Timer Expired (%ld ms)!\n", (now.tv_sec - orig.tv_sec) * 1000 + (now.tv_usec - orig.tv_usec) / 1000); + } + exit(0); +} diff --git a/tonezone.c b/tonezone.c new file mode 100644 index 0000000..e31a803 --- /dev/null +++ b/tonezone.c @@ -0,0 +1,529 @@ +/* + * BSD Telephony Of Mexico "Tormenta" Tone Zone Support 2/22/01 + * + * Working with the "Tormenta ISA" Card + * + * Primary Author: Mark Spencer + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU Lesser General Public License Version 2.1 as published + * by the Free Software Foundation. See the LICENSE.LGPL file + * included with this program for more details. + * + * In addition, when this program is distributed with Asterisk in + * any form that would qualify as a 'combined work' or as a + * 'derivative work' (but not mere aggregation), you can redistribute + * and/or modify the combination under the terms of the license + * provided with that copy of Asterisk, instead of the license + * terms granted here. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dahdi/user.h" +#include "tonezone.h" +#include "dahdi_tools_version.h" + +#define DEFAULT_DAHDI_DEV "/dev/dahdi/ctl" + +#define MAX_SIZE 16384 +#define CLIP 32635 +#define BIAS 0x84 + +#if 0 +# define PRINT_DEBUG(x, ...) printf(x, __VA_ARGS__) +#else +# define PRINT_DEBUG(x, ...) +#endif + +#ifndef ENODATA +#define ENODATA EINVAL +#endif + +struct tone_zone *tone_zone_find(char *country) +{ + struct tone_zone *z; + z = builtin_zones; + while(z->zone > -1) { + if (!strcasecmp(country, z->country)) + return z; + z++; + } + return NULL; +} + +struct tone_zone *tone_zone_find_by_num(int id) +{ + struct tone_zone *z; + z = builtin_zones; + while(z->zone > -1) { + if (z->zone == id) + return z; + z++; + } + return NULL; +} + +#define LEVEL -10 + +static int build_tone(void *data, size_t size, struct tone_zone_sound *t, int *count) +{ + char *dup, *s; + struct dahdi_tone_def *td=NULL; + int firstnobang = -1; + int freq1, freq2, time; + int modulate = 0; + float db = 1.0; + float gain; + int used = 0; + dup = strdup(t->data); + s = strtok(dup, ","); + while(s && strlen(s)) { + /* Handle optional ! which signifies don't start here*/ + if (s[0] == '!') { + s++; + } else if (firstnobang < 0) { + PRINT_DEBUG("First no bang: %s\n", s); + firstnobang = *count; + } + + if (sscanf(s, "%d+%d/%d", &freq1, &freq2, &time) == 3) { + /* f1+f2/time format */ + PRINT_DEBUG("f1+f2/time format: %d, %d, %d\n", freq1, freq2, time); + } else if (sscanf(s, "%d*%d/%d", &freq1, &freq2, &time) == 3) { + /* f1*f2/time format */ + PRINT_DEBUG("f1+f2/time format: %d, %d, %d\n", freq1, freq2, time); + modulate = 1; + } else if (sscanf(s, "%d+%d", &freq1, &freq2) == 2) { + PRINT_DEBUG("f1+f2 format: %d, %d\n", freq1, freq2); + time = 0; + } else if (sscanf(s, "%d*%d", &freq1, &freq2) == 2) { + PRINT_DEBUG("f1+f2 format: %d, %d\n", freq1, freq2); + modulate = 1; + time = 0; + } else if (sscanf(s, "%d/%d", &freq1, &time) == 2) { + PRINT_DEBUG("f1/time format: %d, %d\n", freq1, time); + freq2 = 0; + } else if (sscanf(s, "%d@/%d", &freq1, &time) == 2) { + /* The "@" character has been added to enable an + * approximately -20db tone generation of any frequency This has been done + * primarily to generate the Australian congestion tone. + * Example: "425/375,0/375,425@/375,0/375" + */ + PRINT_DEBUG("f1 reduced amplitude/time format: %d, %d\n", freq1,time); + db = 0.3; + freq2 = 0; + } else if (sscanf(s, "%d", &freq1) == 1) { + PRINT_DEBUG("f1 format: %d\n", freq1); + firstnobang = *count; + freq2 = 0; + time = 0; + } else { + fprintf(stderr, "tone component '%s' of '%s' is a syntax error\n", s,t->data); + return -1; + } + + PRINT_DEBUG("Using %d samples for %d and %d\n", time * 8, freq1, freq2); + + if (size < sizeof(*td)) { + fprintf(stderr, "Not enough space for tones\n"); + return -1; + } + td = data; + + /* Bring it down -8 dbm */ + gain = db*(pow(10.0, (LEVEL - 3.14) / 20.0) * 65536.0 / 2.0); + + td->fac1 = 2.0 * cos(2.0 * M_PI * (freq1 / 8000.0)) * 32768.0; + td->init_v2_1 = sin(-4.0 * M_PI * (freq1 / 8000.0)) * gain; + td->init_v3_1 = sin(-2.0 * M_PI * (freq1 / 8000.0)) * gain; + + td->fac2 = 2.0 * cos(2.0 * M_PI * (freq2 / 8000.0)) * 32768.0; + td->init_v2_2 = sin(-4.0 * M_PI * (freq2 / 8000.0)) * gain; + td->init_v3_2 = sin(-2.0 * M_PI * (freq2 / 8000.0)) * gain; + + td->modulate = modulate; + + data += sizeof(*td); + used += sizeof(*td); + size -= sizeof(*td); + td->tone = t->toneid; + if (time) { + /* We should move to the next tone */ + td->next = *count + 1; + td->samples = time * 8; + } else { + /* Stay with us */ + td->next = *count; + td->samples = 8000; + } + *count += 1; + s = strtok(NULL, ","); + } + if (td && time) { + /* If we don't end on a solid tone, return */ + td->next = firstnobang; + } + if (firstnobang < 0) + fprintf(stderr, "tone '%s' does not end with a solid tone or silence (all tone components have an exclamation mark)\n", t->data); + + return used; +} + +char *tone_zone_tone_name(int id) +{ + static char tmp[80]; + switch(id) { + case DAHDI_TONE_DIALTONE: + return "Dialtone"; + case DAHDI_TONE_BUSY: + return "Busy"; + case DAHDI_TONE_RINGTONE: + return "Ringtone"; + case DAHDI_TONE_CONGESTION: + return "Congestion"; + case DAHDI_TONE_CALLWAIT: + return "Call Waiting"; + case DAHDI_TONE_DIALRECALL: + return "Dial Recall"; + case DAHDI_TONE_RECORDTONE: + return "Record Tone"; + case DAHDI_TONE_CUST1: + return "Custom 1"; + case DAHDI_TONE_CUST2: + return "Custom 2"; + case DAHDI_TONE_INFO: + return "Special Information"; + case DAHDI_TONE_STUTTER: + return "Stutter Dialtone"; + default: + snprintf(tmp, sizeof(tmp), "Unknown tone %d", id); + return tmp; + } +} + +#ifdef TONEZONE_DRIVER +static void dump_tone_zone(void *data, int size) +{ + struct dahdi_tone_def_header *z; + struct dahdi_tone_def *td; + int x; + int len = sizeof(*z); + + z = data; + data += sizeof(*z); + printf("Header: %d tones, %d bytes of data, zone %d (%s)\n", + z->count, size, z->zone, z->name); + for (x = 0; x < z->count; x++) { + td = data; + printf("Tone Fragment %d: tone is %d, next is %d, %d samples\n", + x, td->tone, td->next, td->samples); + data += sizeof(*td); + len += sizeof(*td); + } + printf("Total measured bytes of data: %d\n", len); +} +#endif + +/* Tone frequency tables */ +struct mf_tone { + int tone; + float f1; /* first freq */ + float f2; /* second freq */ +}; + +static struct mf_tone dtmf_tones[] = { + { DAHDI_TONE_DTMF_0, 941.0, 1336.0 }, + { DAHDI_TONE_DTMF_1, 697.0, 1209.0 }, + { DAHDI_TONE_DTMF_2, 697.0, 1336.0 }, + { DAHDI_TONE_DTMF_3, 697.0, 1477.0 }, + { DAHDI_TONE_DTMF_4, 770.0, 1209.0 }, + { DAHDI_TONE_DTMF_5, 770.0, 1336.0 }, + { DAHDI_TONE_DTMF_6, 770.0, 1477.0 }, + { DAHDI_TONE_DTMF_7, 852.0, 1209.0 }, + { DAHDI_TONE_DTMF_8, 852.0, 1336.0 }, + { DAHDI_TONE_DTMF_9, 852.0, 1477.0 }, + { DAHDI_TONE_DTMF_s, 941.0, 1209.0 }, + { DAHDI_TONE_DTMF_p, 941.0, 1477.0 }, + { DAHDI_TONE_DTMF_A, 697.0, 1633.0 }, + { DAHDI_TONE_DTMF_B, 770.0, 1633.0 }, + { DAHDI_TONE_DTMF_C, 852.0, 1633.0 }, + { DAHDI_TONE_DTMF_D, 941.0, 1633.0 }, + { 0, 0, 0 } +}; + +static struct mf_tone mfr1_tones[] = { + { DAHDI_TONE_MFR1_0, 1300.0, 1500.0 }, + { DAHDI_TONE_MFR1_1, 700.0, 900.0 }, + { DAHDI_TONE_MFR1_2, 700.0, 1100.0 }, + { DAHDI_TONE_MFR1_3, 900.0, 1100.0 }, + { DAHDI_TONE_MFR1_4, 700.0, 1300.0 }, + { DAHDI_TONE_MFR1_5, 900.0, 1300.0 }, + { DAHDI_TONE_MFR1_6, 1100.0, 1300.0 }, + { DAHDI_TONE_MFR1_7, 700.0, 1500.0 }, + { DAHDI_TONE_MFR1_8, 900.0, 1500.0 }, + { DAHDI_TONE_MFR1_9, 1100.0, 1500.0 }, + { DAHDI_TONE_MFR1_KP, 1100.0, 1700.0 }, /* KP */ + { DAHDI_TONE_MFR1_ST, 1500.0, 1700.0 }, /* ST */ + { DAHDI_TONE_MFR1_STP, 900.0, 1700.0 }, /* KP' or ST' */ + { DAHDI_TONE_MFR1_ST2P, 1300.0, 1700.0 }, /* KP'' or ST'' */ + { DAHDI_TONE_MFR1_ST3P, 700.0, 1700.0 }, /* KP''' or ST''' */ + { 0, 0, 0 } +}; + +static struct mf_tone mfr2_fwd_tones[] = { + { DAHDI_TONE_MFR2_FWD_1, 1380.0, 1500.0 }, + { DAHDI_TONE_MFR2_FWD_2, 1380.0, 1620.0 }, + { DAHDI_TONE_MFR2_FWD_3, 1500.0, 1620.0 }, + { DAHDI_TONE_MFR2_FWD_4, 1380.0, 1740.0 }, + { DAHDI_TONE_MFR2_FWD_5, 1500.0, 1740.0 }, + { DAHDI_TONE_MFR2_FWD_6, 1620.0, 1740.0 }, + { DAHDI_TONE_MFR2_FWD_7, 1380.0, 1860.0 }, + { DAHDI_TONE_MFR2_FWD_8, 1500.0, 1860.0 }, + { DAHDI_TONE_MFR2_FWD_9, 1620.0, 1860.0 }, + { DAHDI_TONE_MFR2_FWD_10, 1740.0, 1860.0 }, + { DAHDI_TONE_MFR2_FWD_11, 1380.0, 1980.0 }, + { DAHDI_TONE_MFR2_FWD_12, 1500.0, 1980.0 }, + { DAHDI_TONE_MFR2_FWD_13, 1620.0, 1980.0 }, + { DAHDI_TONE_MFR2_FWD_14, 1740.0, 1980.0 }, + { DAHDI_TONE_MFR2_FWD_15, 1860.0, 1980.0 }, + { 0, 0, 0 } +}; + +static struct mf_tone mfr2_rev_tones[] = { + { DAHDI_TONE_MFR2_REV_1, 1020.0, 1140.0 }, + { DAHDI_TONE_MFR2_REV_2, 900.0, 1140.0 }, + { DAHDI_TONE_MFR2_REV_3, 900.0, 1020.0 }, + { DAHDI_TONE_MFR2_REV_4, 780.0, 1140.0 }, + { DAHDI_TONE_MFR2_REV_5, 780.0, 1020.0 }, + { DAHDI_TONE_MFR2_REV_6, 780.0, 900.0 }, + { DAHDI_TONE_MFR2_REV_7, 660.0, 1140.0 }, + { DAHDI_TONE_MFR2_REV_8, 660.0, 1020.0 }, + { DAHDI_TONE_MFR2_REV_9, 660.0, 900.0 }, + { DAHDI_TONE_MFR2_REV_10, 660.0, 780.0 }, + { DAHDI_TONE_MFR2_REV_11, 540.0, 1140.0 }, + { DAHDI_TONE_MFR2_REV_12, 540.0, 1020.0 }, + { DAHDI_TONE_MFR2_REV_13, 540.0, 900.0 }, + { DAHDI_TONE_MFR2_REV_14, 540.0, 780.0 }, + { DAHDI_TONE_MFR2_REV_15, 540.0, 660.0 }, + { 0, 0, 0 } +}; + +static int build_mf_tones(void *data, size_t size, int *count, struct mf_tone *tone, int low_tone_level, int high_tone_level) +{ + struct dahdi_tone_def *td; + float gain; + int used = 0; + + while (tone->tone) { + if (size < sizeof(*td)) { + fprintf(stderr, "Not enough space for samples\n"); + return -1; + } + td = data; + data += sizeof(*td); + used += sizeof(*td); + size -= sizeof(*td); + td->tone = tone->tone; + *count += 1; + + /* Bring it down 6 dBm */ + gain = pow(10.0, (low_tone_level - 3.14) / 20.0) * 65536.0 / 2.0; + td->fac1 = 2.0 * cos(2.0 * M_PI * (tone->f1 / 8000.0)) * 32768.0; + td->init_v2_1 = sin(-4.0 * M_PI * (tone->f1 / 8000.0)) * gain; + td->init_v3_1 = sin(-2.0 * M_PI * (tone->f1 / 8000.0)) * gain; + + gain = pow(10.0, (high_tone_level - 3.14) / 20.0) * 65536.0 / 2.0; + td->fac2 = 2.0 * cos(2.0 * M_PI * (tone->f2 / 8000.0)) * 32768.0; + td->init_v2_2 = sin(-4.0 * M_PI * (tone->f2 / 8000.0)) * gain; + td->init_v3_2 = sin(-2.0 * M_PI * (tone->f2 / 8000.0)) * gain; + + tone++; + } + + return used; +} + +int tone_zone_register_zone(int fd, struct tone_zone *z) +{ + char buf[MAX_SIZE]; + int res; + int count = 0; + int x; + size_t space = MAX_SIZE; + void *ptr = buf; + int iopenedit = 1; + struct dahdi_tone_def_header *h; + + memset(buf, 0, sizeof(buf)); + + h = ptr; + ptr += sizeof(*h); + space -= sizeof(*h); + h->zone = z->zone; + + dahdi_copy_string(h->name, z->description, sizeof(h->name)); + + for (x = 0; x < DAHDI_MAX_CADENCE; x++) + h->ringcadence[x] = z->ringcadence[x]; + + for (x = 0; x < DAHDI_TONE_MAX; x++) { + if (!strlen(z->tones[x].data)) + continue; + + PRINT_DEBUG("Tone: %d, string: %s\n", z->tones[x].toneid, z->tones[x].data); + + if ((res = build_tone(ptr, space, &z->tones[x], &count)) < 0) { + fprintf(stderr, "Tone %d not built.\n", x); + return -1; + } + ptr += res; + space -= res; + } + + if ((res = build_mf_tones(ptr, space, &count, dtmf_tones, z->dtmf_low_level, z->dtmf_high_level)) < 0) { + fprintf(stderr, "Could not build DTMF tones.\n"); + return -1; + } + ptr += res; + space -= res; + + if ((res = build_mf_tones(ptr, space, &count, mfr1_tones, z->mfr1_level, z->mfr1_level)) < 0) { + fprintf(stderr, "Could not build MFR1 tones.\n"); + return -1; + } + ptr += res; + space -= res; + + if ((res = build_mf_tones(ptr, space, &count, mfr2_fwd_tones, z->mfr2_level, z->mfr2_level)) < 0) { + fprintf(stderr, "Could not build MFR2 FWD tones.\n"); + return -1; + } + ptr += res; + space -= res; + + if ((res = build_mf_tones(ptr, space, &count, mfr2_rev_tones, z->mfr2_level, z->mfr2_level)) < 0) { + fprintf(stderr, "Could not build MFR2 REV tones.\n"); + return -1; + } + ptr += res; + space -= res; + + h->count = count; + + if (fd < 0) { + if ((fd = open(DEFAULT_DAHDI_DEV, O_RDWR)) < 0) { + fprintf(stderr, "Unable to open %s and fd not provided\n", DEFAULT_DAHDI_DEV); + return -1; + } + iopenedit = 1; + } + + x = z->zone; + if ((res = ioctl(fd, DAHDI_FREEZONE, &x))) { + if (errno != EBUSY) + fprintf(stderr, "ioctl(DAHDI_FREEZONE) failed: %s\n", strerror(errno)); + return res; + } + +#if defined(TONEZONE_DRIVER) + dump_tone_zone(h, MAX_SIZE - space); +#endif + +#if defined(__FreeBSD__) + if ((res = ioctl(fd, DAHDI_LOADZONE, &h))) { +#else + if ((res = ioctl(fd, DAHDI_LOADZONE, h))) { +#endif + fprintf(stderr, "ioctl(DAHDI_LOADZONE) failed: %s\n", strerror(errno)); + return res; + } + + if (iopenedit) + close(fd); + + return res; +} + +int tone_zone_register(int fd, char *country) +{ + struct tone_zone *z; + z = tone_zone_find(country); + if (z) { + return tone_zone_register_zone(-1, z); + } else { + return -1; + } +} + +int tone_zone_set_zone(int fd, char *country) +{ + int res=-1; + struct tone_zone *z; + if (fd > -1) { + z = tone_zone_find(country); + if (z) + res = ioctl(fd, DAHDI_SETTONEZONE, &z->zone); + if ((res < 0) && (errno == ENODATA)) { + tone_zone_register_zone(fd, z); + res = ioctl(fd, DAHDI_SETTONEZONE, &z->zone); + } + } + return res; +} + +int tone_zone_get_zone(int fd) +{ + int x=-1; + if (fd > -1) { + ioctl(fd, DAHDI_GETTONEZONE, &x); + return x; + } + return -1; +} + +int tone_zone_play_tone(int fd, int tone) +{ + struct tone_zone *z; + int res = -1; + int zone; + +#if 0 + fprintf(stderr, "Playing tone %d (%s) on %d\n", tone, tone_zone_tone_name(tone), fd); +#endif + if (fd > -1) { + res = ioctl(fd, DAHDI_SENDTONE, &tone); + if ((res < 0) && (errno == ENODATA)) { + ioctl(fd, DAHDI_GETTONEZONE, &zone); + z = tone_zone_find_by_num(zone); + if (z) { + res = tone_zone_register_zone(fd, z); + /* Recall the zone */ + ioctl(fd, DAHDI_SETTONEZONE, &zone); + if (res < 0) { + fprintf(stderr, "Failed to register zone '%s': %s\n", z->description, strerror(errno)); + } else { + res = ioctl(fd, DAHDI_SENDTONE, &tone); + } + } else + fprintf(stderr, "Don't know anything about zone %d\n", zone); + } + } + return res; +} diff --git a/tonezone.h b/tonezone.h new file mode 100644 index 0000000..07c5f98 --- /dev/null +++ b/tonezone.h @@ -0,0 +1,90 @@ +/* + * BSD Telephony Of Mexico "Tormenta" Tone Zone Support 2/22/01 + * + * Working with the "Tormenta ISA" Card + * + * Copyright (C) 2001-2008, Digium, Inc. + * + * Primary Author: Mark Spencer + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU Lesser General Public License Version 2.1 as published + * by the Free Software Foundation. See the LICENSE.LGPL file + * included with this program for more details. + * + * In addition, when this program is distributed with Asterisk in + * any form that would qualify as a 'combined work' or as a + * 'derivative work' (but not mere aggregation), you can redistribute + * and/or modify the combination under the terms of the license + * provided with that copy of Asterisk, instead of the license + * terms granted here. + */ + +#ifndef _TONEZONE_H +#define _TONEZONE_H + +#include + +struct tone_zone_sound { + int toneid; + char data[256]; /* Actual zone description */ + /* Description is a series of tones of the format: + [!]freq1[+freq2][/time] separated by commas. There + are no spaces. The sequence is repeated back to the + first tone description not preceeded by !. time is + specified in milliseconds */ +}; + +struct tone_zone { + int zone; /* Zone number */ + char country[10]; /* Country code */ + char description[40]; /* Description */ + int ringcadence[DAHDI_MAX_CADENCE]; /* Ring cadence */ + struct tone_zone_sound tones[DAHDI_TONE_MAX]; + int dtmf_high_level; /* Power level of high frequency component + of DTMF, expressed in dBm0. */ + int dtmf_low_level; /* Power level of low frequency component + of DTMF, expressed in dBm0. */ + int mfr1_level; /* Power level of MFR1, expressed in dBm0. */ + int mfr2_level; /* Power level of MFR2, expressed in dBm0. */ +}; + +extern struct tone_zone builtin_zones[]; + +/* Register a given two-letter tone zone if we can */ +int tone_zone_register(int fd, char *country); + +/* Register a given two-letter tone zone if we can */ +int tone_zone_register_zone(int fd, struct tone_zone *z); + +/* Retrieve a raw tone zone structure */ +struct tone_zone *tone_zone_find(char *country); + +/* Retrieve a raw tone zone structure by id instead of country*/ +struct tone_zone *tone_zone_find_by_num(int id); + +/* Retrieve a string name for a given tone id */ +char *tone_zone_tone_name(int id); + +/* Set a given file descriptor into a given country -- USE THIS + INTERFACE INSTEAD OF THE IOCTL ITSELF. Auto-loads tone + zone if necessary */ +int tone_zone_set_zone(int fd, char *country); + +/* Get the current tone zone */ +int tone_zone_get_zone(int fd); + +/* Play a given tone, loading tone zone automatically + if necessary */ +int tone_zone_play_tone(int fd, int toneid); + +#endif diff --git a/wavformat.h b/wavformat.h new file mode 100644 index 0000000..c7b1626 --- /dev/null +++ b/wavformat.h @@ -0,0 +1,48 @@ +/* + * wavformat.h -- data structures and associated definitions for wav files + * + * By Michael Spiceland (mspiceland@digium.com) + * + * (C) 2009 Digium, Inc. + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#ifndef WAVFORMAT_H +#define WAVFORMAT_H + +#include + +struct wavheader { + /* riff type chunk */ + char riff_chunk_id[4]; + uint32_t riff_chunk_size; + char riff_type[4]; + + /* format chunk */ + char fmt_chunk_id[4]; + uint32_t fmt_data_size; + uint16_t fmt_compression_code; + uint16_t fmt_num_channels; + uint32_t fmt_sample_rate; + uint32_t fmt_avg_bytes_per_sec; + uint16_t fmt_block_align; + uint16_t fmt_significant_bps; + + /* data chunk */ + char data_chunk_id[4]; + uint32_t data_data_size; +} __attribute__((packed)); + +#endif diff --git a/xpp/Makefile b/xpp/Makefile new file mode 100644 index 0000000..12909f2 --- /dev/null +++ b/xpp/Makefile @@ -0,0 +1,202 @@ +PEDANTIC = -ansi -pedantic -std=c99 + +INSTALL = install +INSTALL_DATA = install -m 644 + +# +# Ugly hack to find kernel directories before/after the split +# to kernel/user-space. +# +# These variables should be passed to us. But until then... +# +DAHDI_TOOLSDIR ?= .. +DAHDI_KERNELDIR = + +-include $(DAHDI_TOOLSDIR)/makeopts + +INSTALL_DATA = $(INSTALL) -m 644 + +# In 1.4 those are provided by autoconf through makeopts +prefix ?= /usr +datadir ?= $(prefix)/share +mandir ?= $(datadir)/man +sysconfdir ?= $(prefix)/etc +udevrulesdir ?= $(sysconfdir)/udev/rules.d +INSTALL ?= install + +INSTALL_DATA = $(INSTALL) -m 644 + +SBINDIR = $(prefix)/sbin +DATADIR = $(datadir)/dahdi +MANDIR = $(mandir)/man8 +HOTPLUG_USB_DIR = $(sysconfdir)/hotplug/usb +PERLLIBDIR := $(shell eval `perl -V:sitelib`; echo "$$sitelib") +PERL_DIRS := $(shell cd perl_modules; find * -name '[A-Z]*' -type d| xargs) +PERL_MODS_PAT := *.pm $(PERL_DIRS:%=%/*.pm) +PERL_MODS := $(shell cd perl_modules; echo $(PERL_MODS_PAT)) + +# Variables that should be defined above, but need sane defaults: +# FIXME: Are those values really sane? +HOSTCC ?= $(CC) + +USE_OCTASIC := yes +OCTASIC_DIR := oct612x + +ifneq (no,$(USE_OCTASIC)) + +OCT_OBJS = $(shell $(OCTASIC_DIR)/octasic-helper objects $(OCTASIC_DIR)) +OCT_SRCS = $(shell echo $(OCT_OBJS) | tr -s ' ' '\n' | sed 's/\.o$$/.c/g') +OCT_HERE_OBJS = $(shell echo $(OCT_OBJS) | tr -s ' ' '\n' | sed 's,^.*/,,') +OCT_CFLAGS = $(shell $(OCTASIC_DIR)/octasic-helper cflags $(OCTASIC_DIR)) +OCT_DEFINES = \ + -DPTR_TYPE=uint32_t \ + -DcOCT6100_INTERNAL_SUPER_ARRAY_SIZE=1024 \ + -DcOCT6100_MAX_ECHO_CHANNELS=672 \ + -DcOCT6100_MAX_MIXER_EVENTS=1344 + +ECHO_LOADER_SRC = echo_loader.c parse_span_specs.c +ECHO_LOADER = $(ECHO_LOADER_SRC:.c=.o) +endif + +%.8: % + pod2man --section 8 $^ > $@ || $(RM) $@ +PERL_SCRIPTS = \ + dahdi_registration \ + xpp_sync \ + lsdahdi \ + xpp_blink \ + dahdi_genconf \ + dahdi_hardware \ + twinstar \ + # + +PERL_MANS = $(PERL_SCRIPTS:%=%.8) + +# List all our sources +XUSB_SRCS = xtalk/xusb.c xtalk/xlist.c xtalk/debug.c +XTALK_SRCS = xtalk/xtalk.c +MPPTALK_SRCS = mpptalk.c +ASTRIBANK_SRCS = astribank_usb.c +ABHEXLOAD_SRCS = astribank_hexload.c hexfile.c pic_loader.c +ABTOOL_SRCS = astribank_tool.c +ABALLOW_SRCS = astribank_allow.c astribank_license.c + +SRCS = \ + $(XUSB_SRCS) \ + $(XTALK_SRCS) \ + $(MPPTALK_SRCS) \ + $(ASTRIBANK_SRCS) \ + $(ABHEXLOAD_SRCS) \ + $(ABTOOL_SRCS) \ + $(ABALLOW_SRCS) \ + $(ECHO_LOADER_SRC) + +# Derive object files from source list +XUSB_OBJS = $(XUSB_SRCS:.c=.o) +XTALK_OBJS = $(XTALK_SRCS:.c=.o) $(XUSB_OBJS) +MPPTALK_OBJS = $(MPPTALK_SRCS:.c=.o) $(XTALK_OBJS) +ASTRIBANK_OBJS = $(ASTRIBANK_SRCS:.c=.o) $(MPPTALK_OBJS) +ABHEXLOAD_OBJS = $(ABHEXLOAD_SRCS:.c=.o) $(ASTRIBANK_OBJS) $(ECHO_LOADER) $(OCT_HERE_OBJS) +ABTOOL_OBJS = $(ABTOOL_SRCS:.c=.o) $(ASTRIBANK_OBJS) +ABALLOW_OBJS = $(ABALLOW_SRCS:.c=.o) $(ASTRIBANK_OBJS) + +TARGETS = .perlcheck astribank_is_starting +PROG_INSTALL = astribank_is_starting +MAN_INSTALL = $(PROG_INSTALL:%=%.8) +ifeq (1,$(PBX_USB)) +TARGETS += \ + astribank_tool \ + astribank_hexload \ + astribank_allow \ + test_parse +PROG_INSTALL += astribank_tool astribank_hexload astribank_allow +endif +ifneq (,$(PERLLIBDIR)) +PROG_INSTALL += $(PERL_SCRIPTS) +TARGETS += $(PERL_MANS) +endif + +all: $(TARGETS) + +docs: $(PERL_MANS) + +install: all + $(INSTALL) -d $(DESTDIR)$(SBINDIR) + $(INSTALL) $(PROG_INSTALL) $(DESTDIR)$(SBINDIR)/ + $(INSTALL) -d $(DESTDIR)$(DATADIR) + $(INSTALL) xpp_fxloader astribank_hook $(DESTDIR)$(DATADIR)/ + $(INSTALL) waitfor_xpds $(DESTDIR)$(DATADIR)/ + $(INSTALL) -d $(DESTDIR)$(udevrulesdir) + $(INSTALL_DATA) xpp.rules $(DESTDIR)$(udevrulesdir)/ + $(INSTALL) -d $(DESTDIR)$(MANDIR) + $(INSTALL_DATA) $(MAN_INSTALL) $(DESTDIR)$(MANDIR)/ + $(INSTALL) -d $(DESTDIR)$(HOTPLUG_USB_DIR) + $(INSTALL_DATA) xpp_fxloader.usermap $(DESTDIR)$(HOTPLUG_USB_DIR)/ + # for backward compatibility and for hotplug users: + ln -sf $(DATADIR)/xpp_fxloader $(DESTDIR)$(HOTPLUG_USB_DIR)/ +ifneq (,$(PERLLIBDIR)) + $(INSTALL) -d $(DESTDIR)$(PERLLIBDIR) + for i in $(PERL_DIRS); \ + do \ + $(INSTALL) -d "$(DESTDIR)$(PERLLIBDIR)/$$i"; \ + done + for i in $(PERL_MODS); \ + do \ + $(INSTALL_DATA) "perl_modules/$$i" "$(DESTDIR)$(PERLLIBDIR)/$$i"; \ + done +endif + +CFLAGS += -I. -Ixtalk -Wall -Werror + +astribank_hexload: $(ABHEXLOAD_OBJS) +astribank_hexload: LIBS+=$(EXTRA_LIBS) $(USB_LIB) +astribank_hexload: CFLAGS+=$(OCT_CFLAGS) + +astribank_tool: $(ABTOOL_OBJS) +astribank_tool: LIBS+=$(EXTRA_LIBS) $(USB_LIB) + +astribank_allow: $(ABALLOW_OBJS) +astribank_allow: LIBS+=$(EXTRA_LIBS) $(USB_LIB) + +astribank_is_starting: astribank_is_starting.o +astribank_is_starting: LIBS+=$(EXTRA_LIBS) + +hex2iic: hex2iic.o iic.o hexfile.o + +test_parse: test_parse.o hexfile.o +test_parse: LIBS+=$(EXTRA_LIBS) $(USB_LIB) + +ifneq (no,$(USE_OCTASIC)) +.octasic.depend: $(OCTASIC_DIR)/octasic-helper Makefile ../config.status + $(CC) -MM $(OCT_CFLAGS) \ + `$(OCTASIC_DIR)/octasic-helper objects | \ + tr -s ' ' '\n' | \ + sed -e 's,.*,$(OCTASIC_DIR)/&,' -e 's/\.o$$/.c/'` > $@ + +-include .octasic.depend + +$(OCT_HERE_OBJS): Makefile + $(CC) -c $(CFLAGS) $(OCT_CFLAGS) $(OCT_DEFINES) $(OCT_SRCS) + +endif + + +%: %.o + $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ + +.perlcheck: $(PERL_SCRIPTS) + for i in $^; do perl -I./perl_modules -c $$i || exit 1; done + touch $@ + +clean: + $(RM) .depend .octasic.depend *.o xtalk/*.o $(OCT_HERE_OBJS) $(TARGETS) + +.PHONY: depend +ifeq (1,$(PBX_USB)) +depend: .depend +.depend: *.c *.h xtalk/*.c + @echo "Calculating dependencies" + @if ! $(CC) $(CFLAGS) $(OCT_CFLAGS) -MM $(SRCS) > $@; then $(RM) $@; exit 1; fi + +include .depend +endif diff --git a/xpp/README.Astribank b/xpp/README.Astribank new file mode 100644 index 0000000..2e0001f --- /dev/null +++ b/xpp/README.Astribank @@ -0,0 +1,1677 @@ +Xorcom Astribank Documentation +============================== +Xorcom Team +$Revision$, $Date$ + +This file documents the DAHDI drivers for the Xorcom Channel Bank. + +It is generally a more technical document than the +http://www.xorcom.com/product-manuals/product-manuals.html[Astribank +User Manual] + +An HTML version of the latest version of this document could be found at +http://docs.tzafrir.org.il/dahdi-tools/README.Astribank.html[] + +Introduction +------------ +The Xorcom Astribank is a USB-connected channel-bank. An Astribank may +have up to 4 modules: + +PRI:: + 1, 2 or 4 ports of E1 or T1. Can only be the first (left-most) module + of the Astribank. Note that each port has physically a pair of ports, + where the top one has crossed wiring. + +BRI:: + 2, 4 or 8 ports of BRI. Can only be used as the first (left-most) + module of the Astribank. + +FXO:: + 8 ports of FXO (connector to an analog PSTN line). + +FXS:: + 8 ports of FXS (connector to an analog phone). If used as the first + (left-most) module, it will also have 2 output lines and 4 input lines + that will appear on DAHDI like standard DAHDI ports. The input and + output ports are connected from the two RJ-45 connectors on the right + side of the module. + +There is also a 6FXS-2FXO module that is essentially an FXS module with +six lines instead of 8 (but still with the input and output ports) and +an FXO module of two ports. + + +Building and Installation +------------------------- +Apart from the standard DAHDI build requirements, you also need: + +* *libusb development headers* to build the Astribank firmware tools + (astribank_tool, astribank_hexload, astribank_allow). + This is typically the package libusb-dev on Debian (and derivatives + like Ubuntu) or libusb-devel on RedHat (and derivatives like + CentOS/Trixbox). +* *Echo Canceller Module firmware*: If you have an Astribank with an + echo canceller module, see the following section. + +Follow the build instructions of DAHDI-linux and DAHDI-tools. But +Basically, in dahdi-linux run: + + make + make install # as root + +And later in dahdi-tools: + + ./configure + make + make install # as root + + +Echo Canceller Firmware +~~~~~~~~~~~~~~~~~~~~~~~ +If you install from source, you should copy OCT6104E-256D.ima to the +source tree (before running make install: + + wget http://updates.xorcom.com/astribank/hwec/OCT6104E-256D.ima + mv OCT6104E-256D.ima drivers/dahdi/xpp/firmwares/ + +Alternatively, if you have already installed DAHDI-linux (e.g. from a +binary package that does not include the firmware) you can just copy +it directly to the target directory, /usr/share/dahdi using: + + cd /usr/share/dahdi + wget http://updates.xorcom.com/astribank/hwec/OCT6104E-256D.ima + + +Installation Scenarios +~~~~~~~~~~~~~~~~~~~~~~ +Below are some commented sequences of commands that can be used at some +common scenarios. Those scenarios begin only after you installed the +software (dahdi-linux, dahdi-tools, asterisk, etc.). + +New Installation Scenario +^^^^^^^^^^^^^^^^^^^^^^^^^ +Installing Astribank on a system where there's no existing Astribank. +You install the driver when the Astribank was already connected: + +-------------------------------------------- +# If you had the hardware already connected: Load just the USB firmware +/usr/share/dahdi/xpp_fxloader usb +# (you could use 'load' instead of 'usb' but this is also a good test +# that automatic load through firmware is also in place) +dahdi_hardware -v +# wait until the Astribank has a product ID of 11x2 +sleep 5 # Just wait a little bit +dahdi_hardware -v # now that you see that all's well: +/etc/init.d/dahdi start +# generate configuration: +dahdi_genconf +# Apply it: +dahdi_cfg + +# edit /etc/asterisk/chan_dahdi.conf to #include dahdi-channels.conf or +# copy its content to the end of chan_dahdi.conf +# +# This stops existing DAHDI calls, if any, but does no other harm: +asterisk -rx 'dahdi restart' +-------------------------------------------- + + +Upgrade Scenario +^^^^^^^^^^^^^^^^ +Upgrading is roughly the same as a new installation. But in many cases +you begin with resetting the firmware. + +I also assume here that the configuration is valid, and hence I don't +generate it. + +-------------------------------------------- +# If you need to reset the firmware: +/usr/share/dahdi/xpp_fxloader reset +# (you could use 'load' instead of 'usb' but this is also a good test +# that automatic load through firmware is also in place) +dahdi_hardware -v +# wait until the Astribank has a product ID of 11x2 +sleep 5 # Just wait a little bit +dahdi_hardware -v # now that you see that all's well: +/etc/init.d/dahdi start +# +# This stops existing DAHDI calls, if any, but does no other harm: +asterisk -rx 'dahdi restart' +-------------------------------------------- + + +Sample Configurations +--------------------- +We generally recommend to generate the configuration by using utility +dahdi_genconf which are included with DAHDI. Nevertheless, the following +can serve as reference configurations for a system where Astribank devices +are used. + +Also refer to the general README for documentation of the other DAHDI +configuration files. + +xpp.conf: Astribank Initialization +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +/etc/dahdi/xpp.conf is read by the initialization scripts of Astribank +modules: +----------------------------------------------------------- +# /etc/dahdi/xpp.conf +# +# This file is used to configure the operation +# of init_card_* initialization scripts. +# + +# Adds many more tracing messages that are sent to syslog: +#debug 1 + +# xpd_pri: E1 or T1. The default is E1 for all the ports. +# Setting T1 instead: +#pri_protocol T1 +# +# Or if you actually want to mix E1 and T1: +#pri_protocol/xbus-00/xpd-02 T1 +#pri_protocol/connector:usb-0000:00:1d.7-7/xpd-03 T1 +#pri_protocol/label:usb:0000183/xpd-03 T1 +# If several definitions can refer to a port, the last wins. +# If none applies, the default of E1 holds. + +# FXO: country to adjust settings to: +#opermode FRANCE + +# Don't run power calibration on the FXS units. This can save time +# but can also get you unit randomly disconnect, if badly used: +#fxs_skip_calib 1 +----------------------------------------------------------- + + +xpp_order: Explicitly order Astribanks +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +(This feature is available as of DAHDI 2.2) + +On a system with multiple Astribank you would normally want to guarantee +that Astribanks are registered in the same order regardless of the order +in which they are connected or detected. Assuming that you register them +all at the same time. In order to do that, you should list the +Astribanks explicitly under /etc/dahdi/xpp_order . + +Astribanks that are listed there are registered first (according to the +order of lines in the files). Astribanks not listed there are added +last, and sorted by the 'USB connector' string. + +You can identify an Astribank in two ways: + +Label:: + each Astribank (except some really old ones) has a label . This + identifies the actual Astribank box. + +Connector:: + Identify the path the Astribank is connected through. E.g.: to what + USB port you connected it. + +Identifying an Astribank by the label seems simpler and more +predictable. Though it may have some slightly surprising effects if +replace one Astribank with another. + +The sample configuration file: +----------------------------------------------------------- +# +# This is an optional configuration file for ordering +# Dahdi registration. +# +# It is read from /etc/dahdi/xpp_order. This location +# may be overriden via the environment variable XPPORDER_CONF +# +# Lines may contain: +# - The Astribank label (verbatim) +# - The Astribank connector string (prefixed with @) +# Ordering number of each listed Astribank is determined +# by its position in this file. +# Astribanks not listed in this file, get an ordering +# number of 99 (last). +# +# Astribanks with same ordering number are sorted by their +# connectors (to preserve legacy behaviour). +# +# Examples: +#usb:1234 +#@usb-0000:06:02.2-2 +----------------------------------------------------------- + +In order to generate one that includes all the Astribanks in the system +with the current order in which they are connected, use: + + dahdi_genconf xpporder + +For more technical details see the section <<_registering_in_dahdi>> +below. + + +/etc/dahdi/system.conf +~~~~~~~~~~~~~~~~~~~~~~ + +Astribank 8 +^^^^^^^^^^^ + fxoks=1-14 + +Astribank 6FXS/2FXO +^^^^^^^^^^^^^^^^^^^ + fxoks=1-12 + fxsks=13-14 + +Astribank 16: 8FXS/8FXO +^^^^^^^^^^^^^^^^^^^^^^^ + fxoks=1-14 + fxsks=15-22 + +Astribank 4 BRI +^^^^^^^^^^^^^^^ + # Assumed ports settings: + # Ports 1,3: TE + # Ports 2,4: NT + span=1,1,1,ccs,ami + span=2,0,1,ccs,ami + span=3,2,1,ccs,ami + span=4,0,1,ccs,ami + bchan=1-2,4-5,7-8,10-11 + ; if you applied the bri_dchan patch: + ;dchan=3,6,9,12 + hardhdlc=3,6,9,12 + +Astribank 4 PRI E1 +^^^^^^^^^^^^^^^^^^ + # Assumed ports settings: + # Ports 1,3: TE (CPE) + # Ports 2,4: NT (Net) + span=1,1,1,ccs,hdb3,crc4 + span=2,0,1,ccs,hdb3,crc4 + span=3,2,1,ccs,hdb3,crc4 + span=4,0,1,ccs,hdb3,crc4 + bchan=1-15,17-30,31-45,47-60,61-75,77-90,91-105,107-120 + dchan=16,46,76,106 + +Astribank 4 PRI T1 +^^^^^^^^^^^^^^^^^^ + # Assumed ports settings: + # Ports 1,3: TE (CPE) + # Ports 2,4: NT (Net) + span=1,1,1,esf,b8zs + span=2,0,1,esf,b8zs + span=3,2,1,esf,b8zs + span=4,0,1,esf,b8zs + bchan=1-23,25-47,49-71,73-95 + dchan=24,48,72,96 + + +/etc/asterisk/chan_dahdi.conf +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Astribank 8 +^^^^^^^^^^^ + [channels] + signalling=fxo_ks + ; The real analog ports: + context=from-internal + echocancel=yes + ; echocancelwhenbriged=yes + ; echotraining=no + channel => 1-8 + + ; output ports: + context=astbank-output + channel => 9-10 + ; input ports: + immediate=yes + context=astbank-input + channel => 11-14 + immediate=no + +Astribank 6FXS/2FXO +^^^^^^^^^^^^^^^^^^^ + [channels] + signalling=fxo_ks + ; The real analog ports: + context=from-internal + echocancel=yes + ; echocancelwhenbriged=yes + ; echotraining=no + channel => 1-6 + + ; output ports: + context=astbank-output + channel => 7-8 + ; input ports: + immediate=yes + context=astbank-input + channel => 9-12 + immediate=no + + ; FXO ports + signalling=fxs_ks + context=from-pstn + callerid=asreceived + channel => 13-14 + +Astribank 16: 8FXS/8FXO +^^^^^^^^^^^^^^^^^^^^^^^ + [channels] + signalling=fxo_ks + ; The real analog ports: + context=from-internal + echocancel=yes + ; echocancelwhenbriged=yes + ; echotraining=no + channel => 1-8 + + ; output ports: + context=astbank-output + channel => 9-10 + ; input ports: + immediate=yes + context=astbank-input + channel => 11-14 + immediate=no + + ; FXO ports + signalling=fxs_ks + context=from-pstn + callerid=asreceived + channel => 15-22 + +Astribank 4 BRI +^^^^^^^^^^^^^^^ + ; Assumed ports settings: + ; Ports 1,3: TE + ; Ports 2,4: NT + [channels] + switchtype = euroisdn + callerid = asreceived + + ; TE ports: + signalling = bri_cpe_ptmp + ;signalling = bri_cpe + context = from-pstn + group = 1,11 + channel => 1,2 + + group = 1,13 + channel => 7,8 + + ; NT ports: + signalling = bri_net_ptmp + ;signalling = bri_net + context = from-internal + group = 2,12 + channel => 4,5 + + group = 2,14 + channel => 10,11 + +Astribank 4 PRI E1 +^^^^^^^^^^^^^^^^^^ + ; Assumed ports settings: + ; Ports 1,3: TE + ; Ports 2,4: NT + [channels] + switchtype = euroisdn + callerid = asreceived + + ; TE ports: + signalling = pri_cpe + context = from-pstn + group = 1,11 + channel => 1-15,17-30 + + group = 1,13 + channel => 61-75,77-90 + + ; NT ports: + signalling = pri_net + ;signalling = pri_net + context = from-internal + group = 2,12 + channel => 31-45,47-60 + + group = 2,14 + channel => 91-105,107-120 + +Astribank 4 PRI T1 +^^^^^^^^^^^^^^^^^^ + ; Assumed ports settings: + ; Ports 1,3: TE + ; Ports 2,4: NT + [channels] + switchtype = national + callerid = asreceived + + ; TE ports: + signalling = pri_cpe + context = from-pstn + group = 1,11 + channel => 1-23 + + group = 1,13 + channel => 49-71 + + ; NT ports: + signalling = pri_cpe + ;signalling = pri_net + context = from-internal + group = 2,12 + channel => 25-47 + + group = 2,14 + channel => 73-95 + + +/etc/asterisk/extensions.conf +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Sample dialplan (extensions.conf) for all the above: + +----------------------------------------------------------- +[phones-dahdi] +; With Asterisk 1.4 you will may need to use here 'Zap' instead of +; DAHDI. See Zaptel-to-DAHDI.txt . +; +; 6001 will dial to channel 1, 6020, to DAHDI channel 20, etc. +exten => _6XXX,1,Dial(DAHDI/${EXTEN:1}) +; Useful for debugging trunks. Will potentially allow users to +; bypass context limitations. +;exten => _6XXX.,1,Dial(DAHDI/${EXTEN:1:3}/${EXTEN:4}) + +[trunk] +; A number that begins with 9: dial it through a trunk +; (we put FXO channels and TE channels in group 0). +; The leading 9 is stripped. +exten => _9.,1,Dial(DAHDI/g0/${EXTEN:1}) +; dialing a number that begins with 83 will dial it through +; span 3, and so forth. The two leading digits are stripped. +; (Each digital span is also added to group 10+span number). +exten => _8X.,1,Dial(DAHDI/g1${EXTEN:1:1}/${EXTEN:2}) + +[from-internal] +; The context of FXS ports: analog phones. +; They are allowed to dial to all other phones +include => phones-dahdi +; They are also allowed to call through the trunk: +include => trunk +; some simple tests: +include => astbank-test + +[from-pstn] +; Calls from the PSTN enter here. Redirect calls to an IVR +; or a default extension in the s context here. In this case we +; redirect calls to DAHDI channel 1: +exten => s,1,Dial(DAHDI/1) + +; Alternatively, the following will redirect you to the demo IVR +; from the sample extensions.conf of Asterisk: +include => demo + +; An extra context with some simple tests +[astbank-test] +; 200: echo test +exten => 200,1,Answer +exten => 200,n,Wait(1) +exten => 200,n,Echo() +exten => 200,n,Hangup + +; 203: say extension number. Will only work if caller ID +; is properly set in chan_dahdi.conf / dahdi-channels.conf +exten => 203,1,Answer +exten => 203,n,Wait(1) +exten => 203,n,SayNumber(${CALLERID(num)}) +exten => 203,n,Hangup + +[astbank-input] +exten => s,1,Set(DAHDI_CHAN=${CUT(CHANNEL,-,1)}) +exten => s,n,Set(DAHDI_CHAN=${CUT(DAHDI_CHAN,/,2)}) +; 11 is the number of the first input port. At least in the sample +; configuration below. +;exten => s,n,Set(INPUT_NUM=$[${DAHDI_CHAN}-11)]) +; The sample below just logs the signal. +exten => s,n,NoOp(Got signal from DAHDI Channel ${DAHDI_CHAN}) +; Alternatively: +;exten => s,n,System(run something) + +; No. We did not forget the context astbank-outputs. Output +; ports only get calls from the PBX. Thus they don't need a context +; of their own. Sending them to a context of their on makes +; 'dahdi show channels' in the CLI provide useful display, though. +----------------------------------------------------------- + + +Troubleshooting +--------------- +The following commands provide useful information for debugging: + +lsusb Test +~~~~~~~~~~ +Check USB level status. You can use one of the following utilities for it: + + dahdi_hardware -v + or + lsusb | grep e4e4 + +- Look for the USB Product ID (the second number after e4e4). +- If you see *11x2* (e.g: 1152)- the FPGA firmware has been loaded. + Move on. + dahdi_hardware will also show you some more details if the driver + is loaded while the lsusb will just list the device. +- If it shows something as product ID *11x0* - the USB firmware is not + loaded. Maybe you need to run fxload. Or maybe just unplug and plug again + the device. Also make sure that you have fxload installed. +- If lsusb shows the Product ID as *11x1* - only the USB firmware is loaded + and not the FPGA firmware is loaded. If this is still the case after + a while - either the firmware loading has failed or you don't have + astribank_hexload/astribank_tool. Make sure you have libusb-dev(el) + installed when building DAHDI. After you have installed it, you may need + to re-run ./configure . +- It should list all of your Astribank devices. If it doesn't (for + more than period of time needed for the initial firmware + loading) - Check that the Astribank is connected indeed. + + +DAHDI Registration +~~~~~~~~~~~~~~~~~~ +Check if the Astribank spans are registered with DAHDI: + + dahdi_registration + +- This should give useful results after the drivers have identified + and your devices are initialized. +- It should list all Astribank XPDs. For each of them it should write + "on" or "off". If the registration status is "off", then it means that + the span has not been registered in DAHDI and therefore can not be used + yet. +- Registration is normally done as part of `/etc/init.d/dahdi start`. + If you want to register the spans manually, then run command: + `dahdi_registration on` . + + +DAHDI Level Information +~~~~~~~~~~~~~~~~~~~~~~~ +You can get some information regarding DAHDI channels by running one of the +following commands: + + lsdahdi + or + cat /proc/dahdi/* + +- Those two are almost the same. The lsdahdi produced more correctly sorted + output if you have more than 10 spans, and also make the output listing + looks a little bit nicer. +- You can see if your DAHDI spans and channels were loaded, if + they were configured by dahdi_cfg and if they are in use (typically by + Asterisk). + For example: + Not configured Astribank FXS channel will be displayed as: + + 42 FXS + +- When *dahdi_cfg* has applied the configuration of the channel (from + /etc/dahdi/system.conf), you will see an extra column for the signalling + type of the channel. The same channel after it has been configured: + + 42 FXS FXOKS + +- If a program (which is typically Asterisk) uses it, you'll see: + + 42 FXS FXOKS (In use) + + + +Asterisk Level Information +~~~~~~~~~~~~~~~~~~~~~~~~~~ + asterisk -rx 'dahdi show channels' + +- If you get error "Unable to connect to remote asterisk" then it + means that the Asterisk is not running. It is possible that Asterisk + has failed to start due to misconfigured chan_dahdi.conf or whatever reason. + Check /var/log/asterisk/messages or /var/log/asterisk/full . +- If you get the error that "there is no such command" then it means that + chan_dahdi.so is not loaded. There are two reasons for such problem: + * chan_dahdi.so is not even built. Check if the file exists: + + ls -l /usr/lib/asterisk/modules/chan_dahdi.so + + * the chan_dahdi.so file exists but it is not loaded. Try to load it manually: + + asterisk -rx 'module load chan_dahdi.so' + + * In some cases chan_dahdi failed to load properly and needs to be unloaded + before re-loading: + + asterisk -rx 'module unload chan_dahdi.so' + asterisk -rx 'module load chan_dahdi.so' + +- You see "pseudo" channel only. It means that you have not configured any + channels. If you have configured channels in chan_dahdi.conf, you may + need either to restart the Asterisk or unload/load chan_dahdi.so manually. + You can use the following Asterisk CLI commands for it: `unload chan_dahdi.so` + and `load chan_dahdi.so` + + +Known Issues +~~~~~~~~~~~~ +Empty /proc dir +^^^^^^^^^^^^^^^ +.Symptoms: +- Error message: + + "ERR-xpd_fxo: XBUS-00/XPD-00: Failed initializing registers (-22)" + +- Likewise for all XPDs. +- The directory /proc/xpp exists but is empty (not even the files + 'xbuses' and 'sync'). + +.Cause: +The driver failed to recreate the procfs directory /proc/xpp and hence +everything under it. This is because it has already existed. And it +existed because a process still uses it. This is typically because you +have a shell whose working directory is /proc/xpp or somewhere under +it: + + # lsof /proc/xpp + COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME + bash 2741 root cwd DIR 0,3 0 4026532684 /proc/xpp + +.Fix: +Move that process from that directory, or close the file it uses from +under /proc/xpp and reload the dahdi / xpp drivers. + + +Bad Firmware Version +^^^^^^^^^^^^^^^^^^^^ +.Symptoms: +- An Astribank finishes initialization quickly, the /proc/XBUS-nn + directory has no XPD-mm subdirectories. +- Error in the kernel logs about: + + NOTICE-xpp: XBUS-00: XPD at 00: type=6.0 has bad firmware revision 2.6 + +.Cause: +This is normally caused by an Astribank with an older firmware connected +to a + +The protocol version supported by the firmware will typically be the same +one as in the device initialization scripts installed to +/usr/share/dahdi . Hence if this version installed +`/usr/share/dahdi/init_card_3_29` it will probably include firmware of +protocol version 29. + +.Fix: +Reset the firmware: + + /usr/share/dahdi/xpp_fxloader reset + +Or disconnect the Astribank from the power and reocnnect. On some older +versions of the USB firmware resetting the firmware (or any operation of +astribank_tool) would fail if the driver is loaded. Hence you would need to +run `rmmod xpp_usb` . In the end, reload the drivers. + + +USB Errors at Shutdown +^^^^^^^^^^^^^^^^^^^^^^ +.Symptoms: +You see USB-related errors similar to the following whenever you shut +down the drivers of the Astribank or disconnect its drivers: + + ERR-xpp_usb: XBUS-00: Failed to submit a receive urb + +.Cause: +This is a normal part of the shutdown of the USB connection. + +.Fix: +Ignore them. Unless the USB should not have disconnected at that time. + + +BRI Layer 1 Down +^^^^^^^^^^^^^^^^ +.Symptoms: +With the BRI module only, and not in the middle of an active call, you +notice that suddenly the line goes down. The LED of the port stops +blinking, layer1 not listed as "active" in the bri_info file in +/proc/xpp, and the span is in RED alarm in DAHDI. + +You may also see an error message such as: + + NOTICE-xpd_bri: XBUS-00/XPD-02: D-Chan RX Bad checksum: [2A:01=FC] (252) + +from the exact time of the disconnecting. + +.Cause: +This is expected with most european BRI PtMP providers. If they support +PtMP, they are normally also expected to support ISDN phones, that get +the power from the provider. And thus they shut down the line whenever +there's no active call. + +Sometimes the line is shut down in the middle of a layer 2 message. In +the BRI driver the HDLC decoding/encoding is done in the card. In that +case we may get the above error. + +.Fix: +Normaly this is not a problem. The driver will re-establish a connection +once a new call needs to be made. + + +Astribank in lsusb but not in dahdi_hardware +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.Symptoms: +You fail to find an Astribank device in the output of lsusb . But you +see it in `lsusb | grep e4e4` + +.Cause: +The perl module Dahdi::Hardware currently relies on +/proc/bus/usb/devices (from usbfs) whereas lsusb can use either that or +/dev/bus/usb . + +.Fix: +Usbfs is generally deprecated and some distributions (OpenSUSE, Ubuntu) no +longer mount it by default. Try: + + mount /proc/bus/usb + +and if that doesn't work: + + mount -t usbfs usbfs /proc/bus/usbfs + +However this is generally a cosmetic issue that only affects the listing +in dahdi_hardware. + + +Astribank not initialized: Premature packet end +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.Symptoms: +After upgrading to Zaptel 1.4.12 / 1.2.25 the initialization of the +Astribank times out. In the logs you see: + + kernel: NOTICE-xpp: XBUS-00(00): FIRMWARE: ERROR_CODE CODE = 0x3 (Premature packet end) + +.Cause: +When an Astribank is detected, the driver asks it what is its version +and what components it has. Normally if the version of the firmware and +of the driver does not match the driver gives an ugly message and fails +the initialization. + +However in the change of the protocol between versions 2.9 (29) and 3.0 +(30), the response that the new driver receives from a device with the +old version is now considered to be an illegal packet and gets +discarded. As a result, the Astribank waits till time-out for the +initialization to end. + +.Fix: +Reset the firmware of the Astribank by either: + + /usr/share/dahdi/xpp_fxloader reset + +or disconnecting it from the power and reconnecting it. + + +Reference +--------- +LEDs Indication +~~~~~~~~~~~~~~~ +The Astribank has 4 global indication leds and one or two per-port leds. +On some of the models the LEDs are located on the left side on the front +panel. If there are no separate LEDs there, then the red LEDs of the +upper left-most ports of the device are used as the indication LEDs. Don't +confuse them with green port status LEDs. + +The first led is the "Power" led. It is on if the unit gets power. +The second led is the "Active" led, which is on when there is at +least one "active" port (in a call / off-hook, though the meaning of this is +different in BRI). +The last led is called "Hardware OK", but is actually only is on in case of +the hardware failure. + +The third led is the "Sync" led. If it blinks, the device is synchronized +with the driver on the computer. If the device is selected to be the +synchronization source for all of the Astribank devices then it will blink +a quick single blink. +If the device gets synchronization from the driver, it will blink in a +more steady frequency. + +"Double blink" indicates that the unit has an FXO module, and still is +getting synchronization from the computer, and is not the synchronization +source. + +The per-port green led on analog (both FXS and FXO) indicates that the +port is off-hook. + +On the BRI, the green led indicates a TE port whereas an orange led +indicates an NT port. If the led is solid, the port is down (not even +layer-1 connection is up). If it is blinking a double blink, layer 1 +is up. A slower single blinking indicates that layer 2 is up as well +(which means that Asterisk is driving the port). + +As for the leds of the PRI ports, see the next section. + + +PRI Ports Configuration +~~~~~~~~~~~~~~~~~~~~~~~ +Astribank PRI module has two RJ-45 sockets for each PRI port. The lower +socket provides typical PRI CPE side wiring: Rx- pins 1,2; Tx - pins +4,5. The upper socket provides typical PRI Network side wiring: Rx- pins +4,5; Tx - pins 1,2. The both sockets are permanently active and you can +use any of them regardless of any configuration parameters (Both +connectors are live. And connecting both of them with a flat 8-wire +ethernet cable is a simple way to do a loop test for the port). + +Each port in the PRI module can be configured either as E1 or T1. +The default is E1, but it can be changed in xpp.conf (See the section +above). + +In addition to that, a port defaults to consider itself a CPE, or +rather, to accept timing from the remote party. To override that you +need to set the timing value to 0 (second parameter in the 'span=' line +in system.conf). + +Thus the following in system.conf will also set an orange LED: + + span=2,0,3,ccs,hdb3,crc4 + +Note that as this is only applied when dahdi_cfg is run, the port will have +the default green LED lit at the bottom until it is configured. + + +Voicemail Indication +~~~~~~~~~~~~~~~~~~~~ +Asterisk supports several forms of voicemail message waiting indication +(VMWI) on a phone connected to a FXS port. One of them is a stutter tone +sent when the phone is picked up. Another one is an FSK tone that +encodes the number of messages waiting (or 0, for none). Alternatively it +may send an ioctl call on the channel (DAHDI_VMWI) to indicate the VMWI +status on the channel. + +The DAHDI FXS device may implement any of extra three VMWI notification +methods. The Astribank currently only supports one of them (AC neon LED). +With Asterisk, as of 1.6.2 you can enable that using the following line +in the channel's config in chan_dahdi.conf: + + mwisendtype = neon + +Versions of Asterisk before 1.6.0 did not support this ioctl. You will +need to reset the module parameter <<_vmwi_ioctl,vmwi_ioctl>>. + + +Device Startup +~~~~~~~~~~~~~~ +This section describes in great depth the initialization of the Xorcom +Astribank. Normally it would not be really needed, as the standard +installation of DAHDI should put everything in place. This is generally +some documentation to read when things fail. + +Terminology +^^^^^^^^^^^ +There are some technical terms that are used in this document and in the +driver / dahdi. + +span:: + DAHDI breaks the channels it knows about to logical units called + "spans". A port in a E1/T1/ISDN card is usually a span. An whole + analog card is also a "span". You can see the list of spans as the list + of files under /proc/dahdi directory or in output of the dahdi_tool + utility. + +XBUS:: + A funny way to call an Astribank device. + +XPD:: + Basically this is a logical unit of the Astribank. It will be + registered in DAHDI as a single span. This can be either an analog + (FXS or FXO) module or a single port in case of a BRI module. + + +Loading Firmware +^^^^^^^^^^^^^^^^ +Normally this is done using the script /usr/share/dahdi/xpp_fxloader. +If it works fine, you don't need to bother reading this section. +Once the firmware is loaded the USB Vendor ID and Product ID of the Astribank +became to be e4e4 11x2, and now the driver can pick it up. + +First and foremost: the simplest and most useful tool to debug problems +is lsusb. The output of lsusb should show you if the device is connected +if its firmware is loaded. + +The firmware files are named *.hex. They are presented in the Intel hex +format. The files are copied from xpp/utils to /usr/share/dahdi folder +during the DAHDI installation. + +The Astribank needs a firmware loaded into it. Without the firmware, +the device will appear in lsusb with Vendor ID e4e4 and Product ID 11x0 +(1130, 1140, 1150, 1160 or 1163. 1163 behaves almost exactly as 1160). +The firmware loading process consists of two +stages. In the first stage the "USB" firmware is loaded by using program +fxload. When the first stage is completed the Vendor ID is e4e4 and the +Product ID is 11x1. (e.g. 1151 if it were 1150 previously). + +You can use the following command in order to load the "USB" firmware +manually: + + fxload -t fx2 -D /dev/bus/usb/MMM/NNN -I /usr/share/dahdi/USB_FW.hex + +where, + +fxload:: + A standard program that is typically part either of package 'fxload' + or 'hotplug-utils' . +/dev/bus/usb:: + On some old systems it is missing . /proc/bus/usb (usbfs) could be + used instead. +MMM:: + the first number (bus number) +NNN:: + the second number (device number) you see for the device in lsusb + +If the loading process has been completed successfully, the device +disconnects and then connects again itself with USB Product ID 11x1 +(and a new device number). + +In the second stage, the "FPGA" firmware is loaded. +The second-stage firmware loading is performed by using program +astribank_hexload and astribank_tool, which are built in the directory +xpp/utils and then copied to folder /usr/sbin during DAHDI installation. + +The command syntax is similar to the syntax of fxload. You can use the +following command in order to load the FPGA firmware manually: + + # pick the right name according to the device ID. FPGA_1161.hex is for + # 116x Astribanks: + astribank_hexload -D /dev/bus/usb/MMM/NNN -F /usr/share/dahdi/FPGA_1161.hex + # If the device has an echo canceller unit (If the unit is BRI/E1, you + # need to add an extra -A to the command-line after the -O) + #astribank_hexload -D /dev/bus/usb/MMM/NNN -O /usr/share/dahdi/OCT6104E-256D.ima + # Note the shell expantion in this line: + astribank_hexload -D /dev/bus/usb/MMM/NNN -p /usr/share/dahdi/PIC_TYPE_[1-4].hex + # reenumerate (disconnect and reconnect) + astribank_tool -D /dev/bus/usb/MMM/NNN -n + +Please note, that NNN value differs from that that was used for the +fxload command due to the fact that device has "reconnected" itself +with another Product ID number. So you need to run lsusb again and get +the new NNN value. Usually, the new value is equal to the old value +incremented by 1. + +On newer systems (e.g. Centos 4) /dev/bus/usb may not be available. In +that case, use /proc/bus/usb . usbfs should be mounted there. + + +Automatic Firmware Loading +^^^^^^^^^^^^^^^^^^^^^^^^^^ +Udev is a framework for dynamic device nodes, which is supported in +kernel 2.6. if your udev rules are properly configured then the +firmware should be loaded automatically and you will see product ID 11x2 +(e.g.: 1152). + +Udev is mostly configured by files under /etc/udev/rules.d . The +installer of dahdi-linux installs drivers/dahdi/xpp/xpp.rules into that +directory. + +This file instructs udev to run /usr/share/dahdi/xpp_fxloader for each +time an Astribank connects and needs firmware. When the Astribank loads +firmware or when it resets its firmware it "reenumerates" - disconnects +and reconnects as a new device. + +Below are kernel log messages of an Astribank loading firmware. It firs +connects without any firmware (device no. 44). Udev tells it to load the +USB firmware. It disconnects and reconnects (45). This Udev gets the +FPGA firmware loaded into it. It disconnects again, and when it +reconnects it is now ready to talk with the driver. The last message is +from the driver. +------------------------------------- +usb 7-1: configuration #1 chosen from 1 choice +usb 7-1: New USB device found, idVendor=e4e4, idProduct=1150 +usb 7-1: New USB device strings: Mfr=0, Product=0, SerialNumber =0 +usb 7-1: USB disconnect, address 44 +usb 7-1: new high speed USB device using ehci_hcd and address 45 +usb 7-1: configuration #1 chosen from 1 choice +usb 7-1: New USB device found, idVendor=e4e4, idProduct=1151 +usb 7-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 +usb 7-1: Product: Astribank +usb 7-1: Manufacturer: Xorcom LTD +usb 7-1: SerialNumber: 00000123 +usb 7-1: USB disconnect, address 45 +usb 7-1: new high speed USB device using ehci_hcd and address 46 +usb 7-1: configuration #1 chosen from 1 choice +usb 7-1: reset high speed USB device using ehci_hcd and address 46 +INFO-xpp_usb: XUSB: Xorcom LTD -- Astribank -- FPGA +------------------------------------- + +Another useful tool for tracing UDEV-related issue is the udev monitor: + + udevadm monitor + +Or with some older versions of udev: + + udevmonitor + + +Firmware Loading with Hotplug +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Hotplug is an obsolete framework for doing some of the things done by +udev today. Specifically, handling kernel hotplug events. It is used in +systems with kernel < 2.6.13 (e.g. RHEL4 / Centos4 and Debian 3.1). As +such DAHDI still installs support for those. However if you package +DAHDI for a more recent distribution, you should probably avoid +including those obsolete config files. + +The relevant files installed under /etc/hotplug/usb and are +xpp/xpp_fxloader.usermap and xpp_fxloader (which is a symlink to +/usr/share/dahdi/xpp_fxloader). the usermap file has the same format as +modules.usbmap in the main kernel modules directory: it is intended to +identify a (hotplugged) device. + + +Loading The Modules +^^^^^^^^^^^^^^^^^^^ +Here is what should happen: +In short: you should plug the Astribank device(s) or have them plugged in at +the boot time. Then all the modules should be loaded automatically. +You will see xpp_usb, xpp, and some xpd_* modules in the modules list +(the output of lsmod). + +After the module xpp is loaded, you'll also be able to see the directory +/proc/xpp. For any Astribank device discovered, you will see there a +directory /proc/xpp/XBUS-n (where n is a number: typically 0). Once a unit have +been discovered you'll see subdirectories: /proc/xpp/XBUS-n/XPD-m (where +m may be another number: 0, 1 ,etc). + +Now to the ugly details: + +The driver of the Astribank is composed of several modules: + +xpp:: + The basic module, that communicates with DAHDI and provides some + common services to other modules. +xpd_fxs:: + FXS modules (analog phones). Module type 1. +xpd_fxo:: + FXO modules (Analog PSTN lines). Module type 2. +xpd_bri:: + BRI ("ISDN") modules. Module type 3. +xpd_pri:: + The module for controlling E1/T1 modules. Module type 4. +xpd_echo:: + The module for controlling hardware echo canceller modules. Module type 5. + Does not generate a span. +xpp_usb:: + The functionality needed to connect to the USB bus. + +All modules depend on xpp, and modprobing them will install xpp as well. +However the xpd_* modules are installed on-demand: no need to load +xpd_fxs if you have only Astribank FXS. + +Once an Astribank device connected and the firmware is loaded, the +Vendor-ID/Product-ID of the device will be e4e4/11x2 . The handler for that +combination is listed as the kernel module xpp_usb. Therefore, the system +runs 'modprobe xpp_usb' if that module is not already loaded. + +The module xpp_usb depends on the dahdi and xpp modules. Both of them +are loaded before xpp_usb. As usual, parameters and rules form +/etc/modprobe.conf and/or from /etc/modprobe.d/* will be applied to +the module. + +When command 'modprobe xpp_usb' returns, the span type specific modules +(e.g., xpd_fxs, xpd_fxo) may or may not have been loaded yet. + +At this point the xpp driver "asks" the box about its software +(firmware) version) and the type of telephony modules it has. According +to the answers it receives, the xpp driver will "modprobe" the required +xpd_* modules. + +When an Astribank connects, it tells the driver what ports it has. For +instance, a system with 8BRI (=type 3) ports and 3 modules of 8FXS +(=type 1) ports: +---------------------------------------------- +INFO-xpp: XBUS-00: DESCRIPTOR: 4 cards, protocol revision 30 +INFO-xpp: XBUS-00: CARD 0 type=3.0 ports=8 (2x4), port-dir=0xCC +INFO-xpp: XBUS-00: CARD 1 type=1.0 ports=8 (8x1), port-dir=0xFF +INFO-xpp: XBUS-00: CARD 2 type=1.0 ports=8 (8x1), port-dir=0xFF +INFO-xpp: XBUS-00: CARD 3 type=1.0 ports=8 (8x1), port-dir=0xFF +---------------------------------------------- + +If dahdi, xpp or xpp_usb is missing or defective, you'll get relatively +clear error messages. However if an xpd_* module fails to load (e.g.: +because it is missing), the error is less intuitive: +-------------------------------------------------- +NOTICE-xpp: xproto_get: Failed to load module for type=3. exit status=256. +NOTICE-xpp: XBUS-00: CARD 0: missing protocol table for type 3. Ignored. +-------------------------------------------------- +In this case it was because I maliciously removed the module xpd_bri +(type 3) from the system. + +This can also happen if you accidentally blacklist the relevant xpd-* +module. 'blacklist some_module' in modprobe.conf or modprobe.d/*.conf +means that a direct insmod or modprobe of their name will work, but any +attempt to load a module through its aliases will fail. Recall that the +cpd-* modules are loaded on-demand using the alias 'xpd-type-N' . + + +Device Initializations Scripts +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The chips in the device need to be initialized. This requires sending a +bunch of values to certain registers in those chips. We decided that +hardwiring those values in the driver code is not a good idea. +Before registering a XPD as a span in DAHDI, we run an initialization +script: /usr/share/dahdi/init_card_N_MM where, + +* N is telephony module type: 1 for an FXS span and 2 for an FXO span, + 3 for BRI and 4 for PRI. +* MM - is a version number. Currently it equals 30. + +Those scripts must be executable. If they are not, the initiallization +will do nothing but will give no error, and the device will work in an +unexpected way, if at all. + +If because of some reasons this fails (the script is not in the place, +or the running it produced an error), then you will get an error message +in the logs and the XPD will then be removed (you won't see directory +for that XPD under the corresponding /proc/xpp/XBUS-* directory) and +will not be registered with DAHDI. + +As the XPD is initialized, you'll see the green LEDs of the ports steadily +turn on and later off ("a train of lights"). This is a bit slower than the +faster "blinking" when the XPDs register as DAHDI spans. The initialization +of an FXS XPD may take a few seconds. + + +Connect / Disconnect Hook +^^^^^^^^^^^^^^^^^^^^^^^^^ +When the Astribank has finished initialization it also notifies +userspace applications. This can be used to run a custom command when an +Astribank is connected (after it has finished initialization) or when it +has disconnected. The hook script is installed by default to +/usr/share/dahdi/astribank_hook . + + +Registering in DAHDI +^^^^^^^^^^^^^^^^^^^^ +The XPDs will not automatically register as DAHDI spans. This is +intended to allow you to set the registration order (and hence the order +of DAHDI spans and channels) among multiple Astribank devices, +or between an Astribank and a different DAHDI device. + +When the XPD registers with DAHDI, all the green LEDs will be lit for a +short while. + +Spans are normally registered with the utility dahdi_registration. Simply +running 'dahdi_registration' shows the available XPDs and whether or not +they are registered. To register: + + dahdi_registration on + +For a system with several spans you'll see a "fast train of lights". + +If you have multiple Astribank devices, dahdi_registration will +register them by the ascending order of the USB connector ID. This +means that as long as the same Astribank is connected to the same +port, the order of plugging is not important. + +You can see the USB connector ID in the verbose output of the +dahdi_hardware utility when xpp drivers are loaded. See CONNECTOR value +in the example below: + +------------------------------------------------------ +# dahdi_hardware -v +usb:004/006 xpp_usb+ e4e4:1152 Astribank-multi FPGA-firmware + LABEL=[usb:0000148] CONNECTOR=usb-0000:00:03.3-2 + XBUS-00/XPD-00: E1_TE Span 1 DAHDI-SYNC + XBUS-00/XPD-10: FXS Span 2 + XBUS-00/XPD-20: FXS Span 3 +usb:004/007 xpp_usb+ e4e4:1152 Astribank-multi FPGA-firmware + LABEL=[usb:0000150] CONNECTOR=usb-0000:00:03.3-6 + XBUS-01/XPD-00: FXS Span 4 + XBUS-01/XPD-10: FXO Span 5 +------------------------------------------------------ + +If you have multiple Astribank devices, dahdi_registration will register +them by the order of the "connector" field. This means that as long as +the same Astribank is connected to the same port, the order of plugging +is not important. Alternatively you can set an explicit registration +order using /etc/dahdi/xpp_order . See above in section about +<<_xpp_order_explicitly_order_astribanks,xpp_order>>. + +The registration is performed through the sysfs interface. See below +<<_sys_devices_xpp_xbus_nn_nn_m_p_span,the span attribute>>. Also note +that dahdi_registration also allows you to unregister spans, which will +work for all spans that are not in use (That is: none of their channels +is in use). + +By default, the Astribank drivers don't perform automatic span +registration on DAHDI. It is in contrast to the all known drivers of +PCI boards. Because of that, DAHDI channels related to the PCI board +spans will get lower numbers than the channels related to Astribank +devices. + +You may choose to register the XPDs with DAHDI automatically. This may +make the startup sequence a bit simpler, but is generally not +recommended on a system with more than one Astribank or an Astribank and +a different DAHDI device. This behavior may be defined by setting +parameter <<_dahdi_autoreg>> in the modprobe configuration file (A file under +/etc/modprobe.d or /etc/modprobe.conf): + + options xpp dahdi_autoreg=1 + + +Astribanks Synchronization Source +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +If there is more than one Astribank on the system, all the Astribanks +keep their clock in sync. Optionally the Astribanks can synchronize +their clock to the master DAHDI device (in case it is a different DAHDI +device). Normally you just use the default init.d script or run +explicitly: + + xpp_sync auto + +(For now see the man page of xpp_sync for more information) + + +DAHDI And Above +^^^^^^^^^^^^^^^ +From here you get a standard DAHDI span. The next step is to configure +the span by running the dahdi_cfg utility. You would also need to +configure the channels in the Asterisk chan_dahdi.conf file. Only after +that you will be able to make calls through the telephony ports. + +You can use dahdi_genconf, which is included with dahdi-tools, to +generate a DAHDI and Asterisk configuration for your system. +For analog channels it works quite well, and likewise for BRI. For E1/T1 +it will probably take some tuning. + +Please refer to the general DAHDI documentation for more deatils about +DAHDI and Asterisk configuration. E.g, the README file in the +top-level directory, and + + http://voip-info.org/wiki/view/Asterisk+config+chan_dahdi.conf[] + +Alternatively, write you own configuration, based on the sample from the +"Sample Configurations" section. + + +/proc Interface +~~~~~~~~~~~~~~~ +The Astribank drivers provide their own /proc interface under /proc/xpp. +Here we review the more useful details of the procfs interface. There +are many other debugging details that are exposed through the procfs +interface. + +Also note that those details are subject to changes. Generally the +recommended stable interface are the DAHDI-perl modules and utilities +from the xpp/ directory. + + +/proc/xpp/xbuses +^^^^^^^^^^^^^^^^ +File /proc/xpp/xbuses lists the connected Astribank devices (one line +per device). + +A device is normally has status "connected". The status "missing" means that +the device has been disconnected, but Asterisk still holds channels from it +open. + + +For each Astribank device there is folder /proc/xpp/XBUS-nn and for each device +module (span in the terms of DAHDI) there is folder /proc/XBUS-nn/XPD-mm. + +/proc/xpp/XBUS-nn/XPD-mm/summary +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Contains detailed information about port statuses of the device module +(off-hook, on-hook etc.) For example, you can run the following command +in order to monitor the port statuses in the real time: + + watch -n1 cat /proc/xpp/XBUS-00/XPD-00/summary + + +/proc/xpp/XBUS-nn/XPD-mm/fxo_info +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Only for FXO modules. Apart from showing the status of the LEDs, it also +shows for each FXO port if it is connected to a provider: look for the +value of "battery" for that specific port, and a bunch of other +characteristics of the port. + + +/proc/xpp/XBUS-nn/XPD-mm/bri_info +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +In addition to the usual information about the LEDs, this file also +provides useful information regarding ISDN Layer 1 and Layer 2 status. +For example, you can run the following command in order to monitor +the Layer 1 port statuses for all BRI devices in the real time: + + watch -n1 -d 'grep "Layer 1:" /proc/xpp/XBUS-*/XPD-*/bri_info' + +For the status of the D channel of the ports on all BRI spans, run: + + watch -n1 -d 'grep D-Channel: /proc/xpp/XBUS-*/XPD-*/bri_info' + + +/proc/xpp/XBUS-nn/XPD-mm/pri_info +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +In addition to the usual information about the LEDs, this file also +provides useful information regarding ISDN Layer 1 and Layer 2 status. +For example, you can run the following command in order to monitor +the Layer 1 port statuses for all E1/T1 devices in the real time: + + watch -n1 -d 'grep "Layer 1:" /proc/xpp/XBUS-*/XPD-*/pri_info' + +For the status of the D channel of the ports on all PRI spans, run: + + watch -n1 -d 'grep D-Channel: /proc/xpp/XBUS-*/XPD-*/pri_info' + +Note: the layer 2 status is much more of a guesswork based on changes in +the contents of the channel that is supposed to be the D channel. + + +There are a bunch of other status files under /proc/xpp/. + + +/sys Interface +~~~~~~~~~~~~~~ +Astribanks on the system and the xpds themselves are also represented +in SysFS. SysFS is a virtual file system mounted under /sys and provides +information in a more structured way than ProcFS. In sysfs objects are +represented as directories, simple attributes are shown as files in +the directory of the object and more complex objects are subdirectories +or symbolic links to other directories. + +As with the procfs interface, we only document some interesting +attribuets. Some attributes are writable and hence writing to them +without knowing what you do is not exactly wise. + +Like the procfs interface, this interface is subject to changes and +should not be considered a stable interface. Please use the DAHDI-perl +modules and utilities. + + +Astribanks in SysFS +^^^^^^^^^^^^^^^^^^^ +Each astribank is represented as a device under +/sys/bus/astribanks/devices , with the name xbus-NN, where NN is its +two-digit number (e.g.: 00, 01). + +===== /sys/bus/astribanks/devices/xbus-NN/cls +CLear Statistics: writing to this file clear the procfs statistics for +this Astribank. + +===== /sys/bus/astribanks/devices/xbus-NN/connector +Connector string for the device. The place to which the Astribank is +connected. e.g: usb-0000:00:03.3-2 + +===== /sys/bus/astribanks/devices/xbus-NN/label +The label string of the Astribank unit. E.g: usb:00000135 + +===== /sys/bus/astribanks/devices/xbus-NN/status +'connected' (normal operation) or 'disconnected' (has been disconnected, +some channels are still open). + +===== /sys/bus/astribanks/devices/xbus-NN/timing +Provides some statistics in case the Astribank is not the sync source. +The format of this file is subject to future changes. + +===== /sys/bus/astribanks/devices/xbus-NN/waitfor_xpds +Reading from this file only returns when the Astribank has finished +initialization of the XPDs or in case of a timeout. It prints the number +of XPDs to initialize, and the number initialize. Unless something went +wrong, those two numbers are the same. Once the span was initialized, +reading from this file returns immediately: + + XPDS_READY: XBUS-00: 3/3 + +===== /sys/bus/astribanks/devices/xbus-NN/xbus_state +Reading from it prints the name and number of the state of the +Astribank. This file is also writable: you can write either 'stop' to +disconnect the specific Astribank, or 'start' to reconnect it. + +===== /sys/bus/astribanks/drivers/xppdrv/sync +(An attribute of the generic Astribanks driver) + +The synchronization source. Normally the number of the astribank that is +the synchronization master, or 'SYNC=DAHDI' if Astribanks are +synchronized from a different DAHDI device. Normally you should just use +xpp_sync, though. + +Current possible writable values: + +:: + Make the Astribank XBUS- the sync source for other Astribanks. + +DAHDI:: + Make the Astribanks synchronize with the DAHDI timing master span. + You probably need this to get faxes from a non-Astribank adapter to an + Astribank. + + +XPDs in SysFS +^^^^^^^^^^^^^ +Under the Astribank you'll find a subdirectory for each of its XPDs +("spans"). The name of the directory is composed of three numbers: + +:: + +astribank:: + Two-digit name of the Astribank in which this XPD is in. If it is + xbus-03, you will see there '03'. + +module:: + The number of the Astribank module: from 0 (left-most) to 3 + (right-most). + +subunit:: + In a module that has several spans: the number of the span. In + practice this is only for BRI and PRI and hence the module number will + always be 0 in this case. + +The two-digit number of the XPD in the procfs interface is in fact +. + +Under this you see several attributes. + +===== /sys/bus/astribanks/devices/xbus-NN/NN:M:P/blink +You can write here a number which will be considered to be a bitmask +of the ports that should blink (0 - no blinking). Reading from here +shows that bitmask. If you think that this is complicated, just use +xpp_blink. + +===== /sys/bus/astribanks/devices/xbus-NN/NN:M:P/chipregs +Provides direct read/write interface to the registers of each chip. +Reading from the file shows the result of the last read request. To make +either a read request or a write request you need to write to that file. + +It is mainly used by the initialization scripts (init_card_*). + +Incorrect usage of this file is one possible way of damaging the +Astribank. + +===== /sys/bus/astribanks/devices/xbus-NN/NN:M:P/fxo_battery +(Only on FXO) - shows ports that have (+) or don't have (-) battery +current. That is: which ones are connected to an active FXS on the +other side. + +current. That is: which ones are connected to an active FXS on the +other side. + +===== /sys/bus/astribanks/devices/xbus-NN/NN:M:P/offhook +Shows ports that are (1) or are not (0) off-hook. When a channel is +not off-hook. For BRI and E1/T1 the value is 1 if the span is in use. +This value can also be used to get the number of lines (channels) in +this XPD: the count of items in this list. + +===== /sys/bus/astribanks/devices/xbus-NN/NN:M:P/span +is a read/write file. Reading from it gives 0 if the span is +unregistered, or the span number if it is registered. + +Writing to it allows manual registration / unregistration from DAHDI: +writing 1 registers a span (if it wasn't already registered) and writing +0 attempts to unregister it (if it is registered. Span unregistration +will fail if some channels from the span are used (e.g: by Asterisk). + +A more convenient interface to this is the command dahdi_registration that +registers or unregisters all the spans at once with a predefined order, +and this is what you should normally use. + +Alternatively you can use the parameter dahdi_autoreg to register spans +automatically. But this is only recommended on a system with a single +Astribank and no other DAHDI device. + +===== /sys/bus/astribanks/devices/xbus-NN/NN:M:P/driver +This is a standard sysfs feature: from the directory of the device you +have a link called "driver" to the directory of the driver that +handles it. One specific interesting thing is that this allows you to +easily see all the XPDs of the same type, as they are linked again +from the driver's directory. + + +===== /sys/bus/astribanks/devices/xbus-NN/NN:M:P/pri_protocol +Can have either of those two: + +E1:: + Provides 31 channels, of which channel 16 is normally the D-channel. + Common in places outside of North America and Japan. This is the + default setup. + +T1:: + T1 provides 24 channels. The last one is normally the D-Channel. + Common in North America. + +This can also be set by writing the strings explicitly to the file. But +can only be done when an XPD is not a registered span. + +This writing is normally done by the device initialization script, based +on the 'pri_protocol' settings in +xref:_xpp_conf_astribank_initialization[/etc/dahdi/xpp.conf] . + + +Useful Module Parameters +~~~~~~~~~~~~~~~~~~~~~~~~ +Compilation-time defaults for the all modules can be shown as part of the +description line for the parameter in the "modinfo" command output. + +==== dahdi_autoreg +(xpp) + +Register spans automatically (1) or not (0). Default: 0. +Setting it simplifies operations with a single Astribank and no other +DAHDI hardware. However if you have such systems, automatic +registration can cause the order of spans to be unpredictable. +The standard startup scripts use 'dahdi_registration on' instead of this. + +==== initdir +(xpp) + +This is the directory containing the initialization scripts. +The default is /usr/share/dahdi . +Setting this value could be useful if that location is inconvenient for you. + +==== rx_tasklet +(xpp) + +Enable (1) or disable (0) doing most of the packets processing in +separate tasklets. This should probably help on higher-end systems with +multiple Astribanks. + +==== debug +(all modules) + +It will make the driver to print tons of debugging messages. You can +set/unset the parameter at run-time. The parameter value is a bitmask +of several values. The different bits meaning as it defined in +xpp/dahdi_debug.h: + +* 0 - Disable debug messages +* 1 - GENERAL - General debug comments. +* 2 - PCM - PCM-related messages. Tends to flood logs. +* 4 - LEDS - Anything related to the LEDs status control. The driver + produces a lot of messages when the option is enabled. +* 8 - SYNC - Synchronization related messages. +* 16 - SIGNAL - DAHDI signalling related messages. +* 32 - PROC - Messages related to the procfs interface. +* 64 - REGS - Reading and writing to chip registers. Tends to flood + logs. +* 128 - DEVICES - Device instantiation, destruction and such. +* 256 - COMMANDS - Protocol commands. Tends to flood logs. + +For example, + + echo 33 >/sys/modules/xpp/parameters/debug + +forces module xpp to print general debugging messages (1) and procfs +debugging messages (32). + +==== vmwi_ioctl +(xpd_fxs) + +Does userspace support VMWI notification via ioctl? Default: 1 (yes). + +Disable this (0) to have the driver attempt to detect the voicemail +message waiting indication status for this port from FSK messages +userspace (Asterisk) sends. Set the ports to use AC neon-lamp style +message waiting indication. The detection from the FSK messages takes +extra CPU cycles but is required with e.g. Asterisk 1.4.x . + +Also note that in order for this parameter to take effect, it must be +set before the span is registered. This practically means that it +should be set through modprobe.d files. + +See also <<_voicemail_indication,Voicemail Indication>>. + +==== usb1 +(xpp_usb) + +Enable (1) or disable (0) support of USB1 devices. Disabled by default. + +USB1 devices are not well-tested. It seems that they don't work at all +for Astribank BRI. Generally they should work with the current code, but +we expect the voice quality issues. Hence we would like to make it +very clear that you if you have a USB1 port (rather than a USB2 one, as +recommended) you will have to take an action to enable the device. + +==== poll intervals +(various) + +There are various values which the driver occasionally polls the +device for. For instance, the parameter poll_battery_interval for +xpd_fxo to poll the battery, in order to know if the telco line is +actually connected. + +The value of those parameters is typically a number in milliseconds. +0 is used to disable polling. Under normal operation there should be +no reason to play with those parameters. + +==== dtmf_detection +(xpd_fxs) + +Enable (1) or disable (0) support of hardware DTMF detection by the +Astribank. + +==== caller_id_style +(xpd_fxo) + +Various types of caller ID signalling styles require knowing the PCM +even when the line is on-hook (which is usually a waste of CPU and +bandwidth). This parameter allows fine-tuning the behaviour here: + +* 0 (default) - Don't pass extra PCM when on-hook. +* 1 ETSI-FSK: Wait for polarity reversal to come before a ring and + then start passing PCM until the caller ID has been passed. +* 2 Always: Always pass PCM. + +This parameter is read-only. It cannot be changed at run-time. + +==== battery_threshold +(xpd_fxo) + +Minimum voltage that shows there is battery. Defaults to 3. Normally you +should not need to change this, unless dealing with a funky PSTN +provider. + +==== battery_debounce +(xpd_fxo) + +Minimum interval (msec) for detection of battery off (as opposed to e.g. +a temporary power denial to signal a hangup). Defaults to 1000. As with +battery_threshold above, there's normally no need to tweak it. + + +NOTE: XPP here does not stand for X Printing Panel, XML Pull Parser, +X-Windows Phase Plane or XML Professional Publisher. It is simply the +Xorcom Peripheral Protocol, which connects a computer to a XPD (Xorcom +Peripheral Device). An XBUS (originally XPP Bus) is actually a single +Astribank device and the XPDs have become the single modules in it. diff --git a/xpp/astribank_allow.8 b/xpp/astribank_allow.8 new file mode 100644 index 0000000..2ad8d22 --- /dev/null +++ b/xpp/astribank_allow.8 @@ -0,0 +1,80 @@ +.TH "ASTRIBANK_ALLOW" "8" "29 March 2009" "" "" + +.SH NAME +astribank_allow \- License Xorcom Astribank (xpp) capabilities. +.SH SYNOPSIS +.B astribank_allow \-D \fIdevice-path\fR [ options ] + +.B astribank_allow [\-h] + +.SH DESCRIPTION +Modern Astribanks (with USB product id's 116x) contain capabilities +that may be licensed. + +.B astribank_allow +is used to upload/download the licensing information to/from the device. + +Uploading a valid license file to an Astribank, changes its capabilities. +The change becomes effective after a firmware reset (either by powering +the device off and on again, or via the \fBastribank_tool\fR full reset option). + +Downloading license from the device, produces a valid license file for its +current capabilities. This may be backed up, so the device may be later +restored to its previous capabilities. + +The license file contains both a human readable description of the +device capabilities for the end user and a hash of the licensing +information used by Xorcom to generate/modify licensed capabilities. + +.SH OPTIONS +.B \-D +.I device-path +.RS +Required. The device to read from/write to. This is +\fIbus_num\fR/\fIdevice_num\fR, where \fIbus_num\fR and \fIdevice_num\fR +are the first two numbers in the output of lsusb(8) or dahdi_hardware(8). +On older versions of this tool you needed a complete path to the device, +which would be /dev/bus/usb/\fIbus_num\fR/\fIdevice_num\fR, or +/proc/bus/usb/\fIbus_num\fR/\fIdevice_num\fR. +.RE + +.B \-w +.RS +Write capabilities to EEPROM, otherwise read capabilities +.RE + +.B \-f \fIfilename\fR +.RS +License filename (stdin/stdout if not specified) +.RE + +.B \-m \fInum\fR +.RS +Choose the numeric code of license markers to generate. +This code select the type of \fIBEGIN\fR.../\fIEND\fR... strings +that delimit the license body. + +Valid marker codes are listed with the \fB-h\fR option. +The default (and first) code is \fB1\fR. Zero is illegal value. +.RE + +.B \-v +.RS +Increase verbosity. May be used multiple times. +.RE + +.B \-d \fImask\fR +.RS +Set debug mask to \fImask\fR. Default is 0, 0xFF is "everything". +.RE + +.B \-h +.RS +Displays usage message. +.RE + +.SH SEE ALSO +fxload(8), lsusb(8), astribank_hexload(8), astribank_tool(8) + +.SH AUTHOR +Alex Landau diff --git a/xpp/astribank_allow.c b/xpp/astribank_allow.c new file mode 100644 index 0000000..8f1ea92 --- /dev/null +++ b/xpp/astribank_allow.c @@ -0,0 +1,185 @@ +/* + * Written by Oron Peled and + * Alex Landau + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mpp.h" +#include "mpptalk.h" +#include +#include "astribank_license.h" + +static const char rcsid[] = "$Id$"; + +#define DBG_MASK 0x80 + +static char *progname; + +static void usage() +{ + fprintf(stderr, "Usage: %s [options...] -D {/proc/bus/usb|/dev/bus/usb}// options\n", progname); + fprintf(stderr, "\tOptions:\n"); + fprintf(stderr, "\t\t[-v] # Increase verbosity\n"); + fprintf(stderr, "\t\t[-d mask] # Debug mask (0xFF for everything)\n"); + fprintf(stderr, "\t\t[-w] # Write capabilities to EEPROM, otherwise read capabilities\n"); + fprintf(stderr, "\t\t[-f filename] # License filename (stdin/stdout if not specified)\n\n"); + fprintf(stderr, "\t\t[-m num] # Numeric code of License markers to generate\n"); + license_markers_help("\t", stderr); + exit(1); +} + +static int capabilities_burn( + struct astribank_device *astribank, + struct eeprom_table *eeprom_table, + struct capabilities *capabilities, + struct capkey *key) +{ + int ret; + + INFO("Burning capabilities\n"); + ret = mpp_caps_set(astribank, eeprom_table, capabilities, key); + if(ret < 0) { + ERR("Capabilities burning failed: %d\n", ret); + return ret; + } + INFO("Done\n"); + return 0; +} + +int main(int argc, char *argv[]) +{ + char *devpath = NULL; + struct astribank_device *astribank; + struct eeprom_table eeprom_table; + struct capabilities caps; + struct capkey key; + const char options[] = "vd:D:wf:m:"; + int do_write = 0; + unsigned int marker = LICENSE_MARKER_GENERIC; + FILE *file; + char *filename = NULL; + int ret; + + progname = argv[0]; + while (1) { + int c; + + c = getopt (argc, argv, options); + if (c == -1) + break; + + switch (c) { + case 'D': + devpath = optarg; + break; + case 'v': + verbose++; + break; + case 'd': + debug_mask = strtoul(optarg, NULL, 0); + break; + case 'w': + do_write = 1; + break; + case 'f': + filename = optarg; + break; + case 'm': + marker = strtoul(optarg, NULL, 0); + if (!license_marker_valid(marker)) + usage(); + break; + case 'h': + default: + ERR("Unknown option '%c'\n", c); + usage(); + } + } + if(!devpath) { + ERR("Missing device path\n"); + usage(); + } + DBG("Startup %s\n", devpath); + if((astribank = mpp_init(devpath, 1)) == NULL) { + ERR("Failed initializing MPP\n"); + return 1; + } + if(astribank->eeprom_type != EEPROM_TYPE_LARGE) { + ERR("Cannot use this program with astribank EEPROM type %d (need %d)\n", + astribank->eeprom_type, EEPROM_TYPE_LARGE); + return 1; + } + ret = mpp_caps_get(astribank, &eeprom_table, &caps, &key); + if(ret < 0) { + ERR("Failed to get original capabilities: %d\n", ret); + return 1; + } + if (do_write) { + unsigned int used_marker; + /* update capabilities based on input file */ + file = stdin; + if (filename) { + file = fopen(filename, "r"); + if (file == NULL) { + ERR("Can't open file '%s'\n", filename); + return 1; + } + } + ret = read_from_file(&eeprom_table, &caps, &key, &used_marker, file); + if (ret < 0) { + ERR("Failed to read capabilities from file: %d\n", ret); + return 1; + } + show_capabilities(&caps, stderr); + if (capabilities_burn(astribank, &eeprom_table, &caps, &key) < 0) + return 1; + if (file != stdin) + fclose(file); + } else { + /* print capabilities to stdout */ + file = stdout; + if (filename) { + file = fopen(filename, "w"); + if (file == NULL) { + ERR("Can't create file '%s'\n", filename); + return 1; + } + } + ret = write_to_file(&eeprom_table, &caps, &key, marker, file); + if (ret < 0) { + ERR("Failed to write capabilities to file: %d\n", ret); + return 1; + } + if (file != stdout) + fclose(file); + } + mpp_exit(astribank); + return 0; +} diff --git a/xpp/astribank_hexload.8 b/xpp/astribank_hexload.8 new file mode 100644 index 0000000..27913ff --- /dev/null +++ b/xpp/astribank_hexload.8 @@ -0,0 +1,133 @@ +.TH "ASTRIBANK_HEXLOAD" "8" "30 May 2011" "" "" + +.SH NAME +astribank_hexload \- Xorcom Astribank (xpp) firmware loader +.SH SYNOPSIS +.B astribank_hexload \-D \fIdevice-path\fR \-F [\fIoptions\fR] \fIhexfile\fR + +.B astribank_hexload \-D \fIdevice-path\fR \-p [\fIoptions\fR] \fIhexfile1 .. hexfile4\fR + +.B astribank_hexload \-D \fIdevice-path\fR \-O [-A] [-S \fIspan-specs\fR] [\fIoptions\fR] \fIimagefile\fR + +.B astribank_hexload \-D \fIdevice-path\fR \-o [\fIoptions\fR] + +.B astribank_hexload \-D \fIdevice-path\fR \-E [\fIoptions\fR] \fIhexfile\fR + +.B astribank_hexload \-h + +.SH DESCRIPTION +.B astribank_hexload +is a second-stage firmware loader for Xorcom Astribanks. + +Note that some very old models use fpga_load(8) instead. +This legacy tool hasn't been used for several releases. +It can be found in version 2.6 and below of dahdi-tools. + +The astribank_hexload(8) program is used to load a file in the +Intel HEX format into a Xorcom Astribank. +It can be used to load either an FPGA firmware or a PIC +firmware. It is normally run by the script xpp_fxloader. + +.SH OPTIONS +.B \-D +.I device-path +.RS +Required. The device to read from/write to. This is +\fIbus_num\fR/\fIdevice_num\fR, where \fIbus_num\fR and \fIdevice_num\fR +are the first two numbers in the output of lsusb(8) or dahdi_hardware(8). +On older versions of this tool you needed a complete path to the device, +which would be /dev/bus/usb/\fIbus_num\fR/\fIdevice_num\fR, or +/proc/bus/usb/\fIbus_num\fR/\fIdevice_num\fR. +.RE + +One of the following is required: + +.B \-F +.RS +The firmware to load is a FPGA firmware. +.RE + +.B \-p +.RS +The firmwares to load is are PIC firmwares. All (typically 4) should be +on the command-line. +.RE + +.B \-O +.RS +The firmware to load is an Octasic echo canceller firmware image file. +.RE + +.B \-o +.RS +Don't load firmware. Just print the version number of the currently-loaded +Octasic echo canceller firmware. +.RE + +.B \-E +.RS +The firmware to load is a special EEPROM burning one. +.RE + + +Other options: + +.B \-v +.RS +Increase verbosity. May be used multiple times. +.RE + +.B \-d \fImask\fR +.RS +Set debug mask to \fImask\fR. Default is 0, 0xFF is "everything". +.RE + +.B \-h +.RS +Displays usage message. +.RE + +.B \-A +.RS +When loading a Octasic echo canceller firmware, set the channels of the +first Astribank module to use aLaw (G.711a). This is what you'd normally +use for BRI and E1. If not set, the default mu-Law (G.711u), which is +what you'd normally use for FXS, FXO and T1. +.RE + +.B \-S \fIspan-specs\fR +.RS +This option should only be used when loading Octasic echo canceller firmware +and only if the first Astribank module is PRI. + +Its goal is to allow specifying different \fIline-mode\fR (E1/T1/J1) in different +ports of the PRI module. \fBastribank_hexload\fR use the \fIspan-specs\fR argument +to select aLaw/uLaw for each of the PRI ports in the module. + +The \fIspan-specs\fR is a list of items separated by whitespace or commas. +Each item is composed of a port selector, colon and a \fIline-mode\fR specifier. +This syntax follows the syntax of specifiers in \fB/etc/dahdi/span-types.conf\fR. + +Examples: +.RS +3:E1 \- The 3'rd port is E1. + +*:T1 \- Any unspecified port is T1 (wildcard match). + +1:T1,2:T1,*:E1 \- First and second ports are T1, the rest are E1. +.RE + +If the \fB\-S\fR is not given, the PRI default is determined by the existance of the \fB\-A-fR option. +.RE + +.SH SEE ALSO +fxload(8), lsusb(8), astribank_tool(8) + +.SH AUTHOR +This manual page was written by Tzafrir Cohen . +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common\-licenses/GPL. diff --git a/xpp/astribank_hexload.c b/xpp/astribank_hexload.c new file mode 100644 index 0000000..643fe57 --- /dev/null +++ b/xpp/astribank_hexload.c @@ -0,0 +1,316 @@ +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hexfile.h" +#include "mpptalk.h" +#include "pic_loader.h" +#include "echo_loader.h" +#include "astribank_usb.h" +#include "../autoconfig.h" + +#define DBG_MASK 0x80 +#define MAX_HEX_LINES 64000 +#define HAVE_OCTASIC 1 +#define DEF_SPAN_SPEC_FORMAT "*:%c1" /* %c: 'E' or 'T' */ + +static char *progname; + +static void usage() +{ + fprintf(stderr, "Usage: %s [options...] -D {/proc/bus/usb|/dev/bus/usb}// hexfile...\n", progname); + fprintf(stderr, "\tOptions: {-F|-p}\n"); + fprintf(stderr, "\t\t[-E] # Burn to EEPROM\n"); +#if HAVE_OCTASIC + fprintf(stderr, "\t\t[-O] # Load Octasic firmware\n"); + fprintf(stderr, "\t\t[-o] # Show Octasic version\n"); + fprintf(stderr, "\t\t[-S ] # Set PRI type specification string\n"); +#endif + fprintf(stderr, "\t\t[-F] # Load FPGA firmware\n"); + fprintf(stderr, "\t\t[-p] # Load PIC firmware\n"); + fprintf(stderr, "\t\t[-v] # Increase verbosity\n"); + fprintf(stderr, "\t\t[-A] # Set A-Law for 1st module\n"); + fprintf(stderr, "\t\t[-d mask] # Debug mask (0xFF for everything)\n"); + exit(1); +} + +int handle_hexline(struct astribank_device *astribank, struct hexline *hexline) +{ + uint16_t len; + uint16_t offset_dummy; + uint8_t *data; + int ret; + + assert(hexline); + assert(astribank); + if(hexline->d.content.header.tt != TT_DATA) { + DBG("Non data record type = %d\n", hexline->d.content.header.tt); + return 0; + } + len = hexline->d.content.header.ll; + offset_dummy = hexline->d.content.header.offset; + data = hexline->d.content.tt_data.data; + if((ret = mpp_send_seg(astribank, data, offset_dummy, len)) < 0) { + ERR("Failed hexfile send line: %d\n", ret); + return -EINVAL; + } + return 0; +} + +void print_parse_errors(int level, const char *msg, ...) +{ + va_list ap; + + if (verbose > level) { + va_start (ap, msg); + vfprintf (stderr, msg, ap); + va_end (ap); + } +} + +static int load_hexfile(struct astribank_device *astribank, const char *hexfile, enum dev_dest dest) +{ + struct hexdata *hexdata = NULL; + int finished = 0; + int ret; + unsigned i; + char star[] = "+\\+|+/+-"; + const char *devstr; + + parse_hexfile_set_reporting(print_parse_errors); + if((hexdata = parse_hexfile(hexfile, MAX_HEX_LINES)) == NULL) { + perror(hexfile); + return -errno; + } + devstr = xusb_devpath(astribank->xusb); + INFO("%s [%s]: Loading %s Firmware: %s (version %s)\n", + devstr, + xusb_serial(astribank->xusb), + dev_dest2str(dest), + hexdata->fname, hexdata->version_info); + if((ret = mpp_send_start(astribank, dest, hexdata->version_info)) < 0) { + ERR("%s: Failed hexfile send start: %d\n", devstr, ret); + return ret; + } + for(i = 0; i < hexdata->maxlines; i++) { + struct hexline *hexline = hexdata->lines[i]; + + if(!hexline) + break; + if(verbose > LOG_INFO) { + printf("Sending: %4d%% %c\r", (100 * i) / hexdata->last_line, star[i % sizeof(star)]); + fflush(stdout); + } + if(finished) { + ERR("%s: Extra data after End Of Data Record (line %d)\n", devstr, i); + return 0; + } + if(hexline->d.content.header.tt == TT_EOF) { + DBG("End of data\n"); + finished = 1; + continue; + } + if((ret = handle_hexline(astribank, hexline)) < 0) { + ERR("%s: Failed hexfile sending in lineno %d (ret=%d)\n", devstr, i, ret);; + return ret; + } + } + if(verbose > LOG_INFO) { + putchar('\n'); + fflush(stdout); + } + if((ret = mpp_send_end(astribank)) < 0) { + ERR("%s: Failed hexfile send end: %d\n", devstr, ret); + return ret; + } +#if 0 + fclose(fp); +#endif + free_hexdata(hexdata); + DBG("hexfile loaded successfully\n"); + return 0; +} + +int main(int argc, char *argv[]) +{ + char *devpath = NULL; + int opt_pic = 0; + int opt_echo = 0; + int opt_ecver = 0; +#if HAVE_OCTASIC + int opt_alaw = 0; + const char *span_spec = NULL; + char def_span_spec[sizeof(DEF_SPAN_SPEC_FORMAT)]; +#endif + int opt_dest = 0; + int opt_sum = 0; + enum dev_dest dest = DEST_NONE; + const char options[] = "vd:D:EFOopAS:"; + int iface_num; + int ret; + + progname = argv[0]; + while (1) { + int c; + + c = getopt (argc, argv, options); + if (c == -1) + break; + + switch (c) { + case 'D': + devpath = optarg; + break; + case 'E': + if(dest != DEST_NONE) { + ERR("The -F and -E options are mutually exclusive.\n"); + usage(); + } + opt_dest++; + dest = DEST_EEPROM; + break; + case 'F': + if(dest != DEST_NONE) { + ERR("The -F and -E options are mutually exclusive.\n"); + usage(); + } + opt_dest++; + dest = DEST_FPGA; + break; +#if HAVE_OCTASIC + case 'O': + opt_echo = 1; + break; + case 'o': + opt_ecver = 1; + break; + case 'A': + opt_alaw = 1; + break; + case 'S': + span_spec = optarg; + break; +#endif + case 'p': + opt_pic = 1; + break; + case 'v': + verbose++; + break; + case 'd': + debug_mask = strtoul(optarg, NULL, 0); + break; + case 'h': + default: + ERR("Unknown option '%c'\n", c); + usage(); + } + } + opt_sum = opt_dest + opt_pic + opt_echo; + if(opt_sum > 1 || (opt_sum == 0 && opt_ecver == 0)) { + ERR("The -F, -E" +#if HAVE_OCTASIC + ", -O" +#endif + " and -p options are mutually exclusive, if neither is used then -o should present\n"); + usage(); + } + iface_num = (opt_dest) ? 1 : 0; + if(!opt_pic && !opt_ecver) { + if(optind != argc - 1) { + ERR("Got %d hexfile names (Need exactly one hexfile)\n", + argc - 1 - optind); + usage(); + } + } + if(!devpath) { + ERR("Missing device path.\n"); + usage(); + } +# ifdef HAVE_OCTASIC + if (!span_spec) { + snprintf(def_span_spec, sizeof(def_span_spec), + DEF_SPAN_SPEC_FORMAT, opt_alaw? 'E' : 'T'); + span_spec = def_span_spec; + } +#endif + if(opt_dest) { + /* + * MPP Interface + */ + struct astribank_device *astribank; + + if((astribank = mpp_init(devpath, iface_num)) == NULL) { + ERR("%s: Opening astribank failed\n", devpath); + return 1; + } + //show_astribank_info(astribank); + if(load_hexfile(astribank, argv[optind], dest) < 0) { + ERR("%s: Loading firmware to %s failed\n", devpath, dev_dest2str(dest)); + return 1; + } + astribank_close(astribank, 0); + } else if(opt_pic || opt_echo || opt_ecver) { + /* + * XPP Interface + */ + struct astribank_device *astribank; + + if((astribank = astribank_open(devpath, iface_num)) == NULL) { + ERR("%s: Opening astribank failed\n", devpath); + return 1; + } + //show_astribank_info(astribank); +#if HAVE_OCTASIC + if (opt_ecver) { + if((ret = echo_ver(astribank)) < 0) { + ERR("%s: Get Octasic version failed (Is Echo canceller card connected?)\n", devpath); + return 1; + } else + INFO("Octasic version: 0x%0X\n", ret); + } +#endif + if (opt_pic) { + if ((ret = load_pic(astribank, argc - optind, argv + optind)) < 0) { + ERR("%s: Loading PIC's failed\n", devpath); + return 1; + } +#if HAVE_OCTASIC + } else if (opt_echo) { + if((ret = load_echo(astribank, argv[optind], opt_alaw, span_spec)) < 0) { + ERR("%s: Loading ECHO's failed\n", devpath); + return 1; + } +#endif + } + astribank_close(astribank, 0); + } + return 0; +} diff --git a/xpp/astribank_hook b/xpp/astribank_hook new file mode 100755 index 0000000..fdfa82a --- /dev/null +++ b/xpp/astribank_hook @@ -0,0 +1,234 @@ +#! /bin/sh + +me=`basename $0` +dir=`dirname $0` +LOGGER="logger -i -t '$me'" + +# Always redirect stderr somewhere, otherwise the shell script will die +# when it tries to do I/O related stuff on closed file descriptor. +# Our default is to throw it down the bit-bucket. +#exec 2> /dev/console +## If you wish to trace this script: +#exec 2> "/tmp/${me}_$XBUS_NAME" 1>&2 + +# Our directory in the beginning, so we can use local lab setup +PATH="$dir:/usr/sbin:/sbin:/usr/bin:/bin" + +set -e + +LOCK="/var/lock/twinstar_startup" + +[ -r /etc/dahdi/init.conf ] && . /etc/dahdi/init.conf + +# For lab testing +liveconf="$dir/liveconf/dahdi" + +if [ -d "$liveconf" ]; then + dahdi_conf="$liveconf" +else + dahdi_conf="/etc/dahdi" +fi + +if [ "$XPP_HOTPLUG_DAHDI" != yes ]; then + exit 0 +fi + +export XPPORDER_CONF="$dahdi_conf/xpp_order" +export DAHDI_CFG_CMD="dahdi_cfg -c $dahdi_conf/system.conf" +export CALLED_FROM_ATRIBANK_HOOK=yes + +can_full_async() { + # Can we work aynchronously: + # - Need modern Asterisk that accept hotplug DAHDI devices. + # - Need DAHDI with "auto_assign_spans" == 0 + if [ "$ASTERISK_SUPPORTS_DAHDI_HOTPLUG" = yes ]; then + aas_param='/sys/module/dahdi/parameters/auto_assign_spans' + aas=`cat "$aas_param" 2>/dev/null` + if [ "$aas" = 0 ]; then + return 0 + else + $LOGGER "No async operation ($aas_param != 0)" + fi + else + $LOGGER "No async operation (ASTERISK_SUPPORTS_DAHDI_HOTPLUG!=yes)" + fi + return 1 +} + +check_xpporder_conf() { + if [ ! -r "$XPPORDER_CONF" ]; then + ( + echo "Skip($ACTION): No '$XPPORDER_CONF'" + echo "Removing uneeded startup semaphore" + astribank_is_starting -v -r 2>&1 + ) 2>&1 | $LOGGER + exit 0 + fi +} + +clean_lines() { + sed -e 's/#.*//' -e 'y/\t/ /' -e 's/^ *//' -e 's/ *$//' -e '$s/$/\n/' "$XPPORDER_CONF" +} + +matched_devices() { + ready=`grep -H READY /sys/bus/astribanks/devices/*/xbus_state | sed 's,/xbus_state.*,,'` + for dev in $ready + do + label=`cat "$dev/label"` + connector=`cat "$dev/connector"` + xbus=`echo "$dev" | sed 's,.*/,,'` + lineno=`clean_lines | egrep -n "^${label}$|^@${connector}$" | cut -d: -f1` + if [ "$lineno" != "" ]; then + #echo "$xbus: $XPPORDER_CONF:$lineno -- Match ${label} @${connector}" | $LOGGER + printf "${xbus}\t${label}\n" + else + echo "${xbus}: ${label} @${connector} not found in $XPPORDER_CONF: Ignore($ACTION)" | $LOGGER + fi + done +} + +# Wait until udev finished processing our requests +# so we know the device files were actually created +# before trying dahdi_cfg et-al. +wait_for_udev() { + UDEV_SETTLE_MAX_TIME=10 + + echo "Waiting for udev to settle down..." + if [ -x /sbin/udevsettle ]; then + # Old system, stand-alone udevsettle command + /sbin/udevsettle --timeout="$UDEV_SETTLE_MAX_TIME" + elif [ -x /sbin/udevadm ]; then + # Assume modern system, udevadm has settle parameter + if ! /sbin/udevadm settle --timeout="$UDEV_SETTLE_MAX_TIME" + then + echo "udevadm failed ($?)." + echo "Fallback to sleep $UDEV_SETTLE_MAX_TIME seconds." + sleep "$UDEV_SETTLE_MAX_TIME" + fi + else + echo "No udevsettle/udevadm." + echo "Fallback to sleep $UDEV_SETTLE_MAX_TIME seconds." + sleep "$UDEV_SETTLE_MAX_TIME" + fi + sleep 1 # Wait a bit more (races) +} + +start_dahdi() { + wait_for_udev + script=/etc/init.d/dahdi + echo "Starting $script." + "$script" start | logger -i -t "$script" + status=$? + echo "Status($script): $status" + if [ -x "$dir/twinstar_hook" ]; then + "$dir/twinstar_hook" + fi + # Finished astribanks + echo "Removing semaphore" + astribank_is_starting -v -r + rm -f "$LOCK" +} + +old_synchronous_start() { + NUM_GOOD=`matched_devices | wc -l` + NUM_WANTED=`clean_lines | sed '/^$/d' | wc -l` + echo "$ACTION($XBUS_NAME): $NUM_GOOD/$NUM_WANTED from $XPPORDER_CONF" | $LOGGER + if [ "$NUM_GOOD" -eq "$NUM_WANTED" ]; then + ( + # Delay the initialization of the Astribank until the filesystem + # is mounted read-write: + test_file="/var/lock/astribank_test_file" + for i in `seq 1 20`; do + if touch $test_file 2> /dev/null; then + rm -f $test_file + break + else + echo "$0: [$i] - Failed writing '$test_file'...waiting" | $LOGGER + sleep 1; + fi + done + + if ln -s "$XBUS_NAME" "$LOCK"; then + echo "START-DAHDI: Total $NUM_GOOD online." | $LOGGER + # Fork services + start_dahdi < /dev/null 2>&1 | $LOGGER + else + echo "$0: Was started: $(ls -l $LOCK)" | $LOGGER + fi + ) < /dev/null 2>&1 | $LOGGER & + fi +} + +old_synchronous_stop() { + NUM_GOOD=`matched_devices | wc -l` + NUM_WANTED=`clean_lines | sed '/^$/d' | wc -l` + echo "$ACTION($XBUS_NAME): $NUM_GOOD/$NUM_WANTED from $XPPORDER_CONF" | $LOGGER + if [ "$NUM_GOOD" -eq 0 ]; then + echo "All Astribanks offline" | $LOGGER + if [ -x "$dir/twinstar_hook" ]; then + "$dir/twinstar_hook" || : + fi + rm -f "$LOCK" + fi +} + +ab_list() { + find /sys/devices -name idVendor 2>/dev/null | \ + xargs grep -H 'e4e4' 2>/dev/null | \ + sed -e 's/idVendor.*/idProduct/' | xargs grep -H '11[3456]' | \ + sed 's,/[^/]*$,,' || : +} + +tws_watchdog_enable() { + devdir="/sys$DEVPATH" + label=`cat "$devdir/label"` + connector=`cat "$devdir/connector"` + xbus=`echo "$devdir" | sed 's,.*/,,'` + prefix="${xbus}: [${label}] @${connector}" + TWS_NOAUTOJUMPFILE="$TWS_DIR/twinstar_no_autojump" + if [ -e "$TWS_NOAUTOJUMPFILE" ]; then + $LOGGER "$prefix: ignore wd (found $TWS_NOAUTOJUMPFILE)" + else + # Re-arm Astribank watchdog + transportdir="$devdir/transport" + busnum=`cat "$transportdir/busnum" 2>/dev/null || :` + devnum=`cat "$transportdir/devnum" 2>/dev/null || :` + devaddr=`printf "%03d/%03d" "$busnum" "$devnum"` + $LOGGER "$prefix: enabling twinstar watchdog" + astribank_tool -D "$devaddr" -w 1 2>&1 | $LOGGER + fi +} + +#echo "$0: $ACTION($XBUS_NAME)" | $LOGGER +case "$ACTION" in +add) + ;; +remove) + ab=`ab_list | wc -l` + if [ "$ab" -eq 0 ]; then + $LOGGER "$prefix: No more Astribanks -- remove astribank_is_starting semaphore" + astribank_is_starting -v -r 2>&1 | $LOGGER + fi + ;; +online) + if can_full_async; then + tws_watchdog_enable + else + old_synchronous_start + fi + ;; +offline) + if can_full_async; then + : # Nothing to do + else + old_synchronous_stop + fi + ;; +*) + echo "$0: Unknown ACTION='$ACTION'" | $LOGGER + echo "$0: ARGS='$*'" | $LOGGER + echo "$0: ENV:" | $LOGGER + env | $LOGGER + exit 1 +esac + diff --git a/xpp/astribank_is_starting.8 b/xpp/astribank_is_starting.8 new file mode 100644 index 0000000..5ad0be1 --- /dev/null +++ b/xpp/astribank_is_starting.8 @@ -0,0 +1,100 @@ +.TH "ASTRIBANK_IS_STARTING" "8" "16 August 2009" "" "" + +.SH NAME +astribank_is_starting \- Mark / check is a Xorcom Astribank (xpp) is starting +.SH SYNOPSIS +.B astribank_is_starting [\-d] [\-v] [\-t \fItimeout\fB] <\-a|\-r|\-w> + +.B astribank_is_starting [\-d] [\-v] + +.B astribank_is_starting \-h + +.SH DESCRIPTION +.B astribank_is_starting +is an internal tool used by various xpp scripts to mark that there may +be an Astribank device currently initializing, and to check for that mark. + +Technically the mark is a SysV semaphore. + +.SH OPTIONS +.B \-a +.RS +.B Add. +Set the mark. Should return 0 unless there's an error. +.RE + +.B \-r +.RS +.B Remove. +Reset the mark. Should return 0 unless there's an error. +.RE + +.BI \-t timeout +.RS +.B Timeout. +Set the timeout value for the \fB\-w\fR option. Default is 60 seconds. +.RE + +.B \-w +.RS +.B Wait. +Wait for mark to be reset. Should return 0 unless there's an error. +.RE + +Without \-a or \-r: return 0 if the mark has been set, or a non-zero value +otherwise. + +.B \-d +.RS +Print debug information to stderr. +.RE + +.B \-v +.RS +Verbose execution. +.RE + +.B \-h +.RS +Displays usage message. +.RE + +.SH FILES +.B /proc/sysvipc/sem +.RS +If set, the astribank should appear there with the ID 11211168 (0xAB11A0). +Naturally the ID (or rather, the usage of a semaphore in the first place) +is an implementation detail that may change. +.RE + +.SH NOTES +.B astribank_is_starting +is used to mark the fact that an Astribank may be currently reenumerating +(technically: distonnecting and connecting as a new USB device) after +loading the firmware. Thus the script that loads the firmware +(/usr/share/dahdi/xpp_fxloader) uses this utility to set the mark. + +The mark is reset by /usr/share/dahdi/waitfor_xpds , which is typically +run by the DAHDI init script and waits for all Astribanks to finish +loading. + +Q: Why do you use a semaphore? + +A: because, unlike the filesystem, it is writable at any given time. + +.SH BUGS +Option ordering matter. The \fB\-v\fR and \fB\-d\fR options should preceed +the actions (\fB\-a\fR, \fB\-r\fR and \fB\-w\fR). +The \fB\-t\fItimeout\fR option should preceed the \fB\-w\fR option. + +.SH SEE ALSO +semctl(3) + +.SH AUTHOR +This manual page was written by Tzafrir Cohen . +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common\-licenses/GPL. diff --git a/xpp/astribank_is_starting.c b/xpp/astribank_is_starting.c new file mode 100644 index 0000000..da565c9 --- /dev/null +++ b/xpp/astribank_is_starting.c @@ -0,0 +1,196 @@ +#include "../autoconfig.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char *progname; +static const key_t key_astribanks = 0xAB11A0; +static int debug; +static int verbose; +static int timeout_seconds = 60; + +/* If libc provides no timeout variant: try to do without it: */ +#ifndef HAVE_SEMTIMEDOP +#define semtimedop(sem, ops, n, timeout) semop(sem, ops, n) +#endif + +static void usage(void) +{ + fprintf(stderr, "Usage: %s [-d] [-t ] [-a|-r|-w]\n", progname); + exit(1); +} + +static int absem_get(int createit) +{ + int flags = (createit) ? IPC_CREAT | 0644 : 0; + int absem; + + if((absem = semget(key_astribanks, 1, flags)) < 0) + absem = -errno; + return absem; +} + +static int absem_touch(void) +{ + int absem; + + if((absem = absem_get(1)) < 0) { + perror(__FUNCTION__); + return absem; + } + if(semctl(absem, 0, SETVAL, 0) < 0) { + perror("SETVAL"); + return -errno; + } + if(debug) + fprintf(stderr, "%s: touched absem\n", progname); + if(verbose) + printf("Astribanks initialization is starting\n"); + return 0; +} + +static int absem_remove(void) +{ + int absem; + + if((absem = absem_get(0)) < 0) { + if(absem == -ENOENT) { + if(debug) + fprintf(stderr, "%s: absem already removed\n", progname); + return 0; + } + perror(__FUNCTION__); + return absem; + } + if(semctl(absem, 0, IPC_RMID, 0) < 0) { + perror("RMID"); + return -errno; + } + if(debug) + fprintf(stderr, "%s: removed absem\n", progname); + if(verbose) + printf("Astribanks initialization is done\n"); + return 0; +} + +static int absem_wait(void) +{ + int absem; + struct sembuf sops; + long now; + long start_wait; + struct timespec timeout; + + if((absem = absem_get(0)) < 0) { + perror(__FUNCTION__); + return absem; + } + sops.sem_num = 0; + sops.sem_op = -1; + sops.sem_flg = 0; + start_wait = time(NULL); + timeout.tv_sec = timeout_seconds; + timeout.tv_nsec = 0; + if(semtimedop(absem, &sops, 1, &timeout) < 0) { + switch(errno) { + case EIDRM: /* Removed -- OK */ + break; + case EAGAIN: /* Timeout -- Report */ + fprintf(stderr, "Astribanks waiting timed out\n"); + return -errno; + default: /* Unexpected errors */ + perror("semop"); + return -errno; + } + /* fall-thgough */ + } + now = time(NULL); + if(debug) + fprintf(stderr, "%s: waited on absem %ld seconds\n", progname, now - start_wait); + if(verbose) + printf("Finished after %ld seconds\n", now - start_wait); + return 0; +} + +static int absem_detected(void) +{ + int absem; + + if((absem = absem_get(0)) < 0) { + if(debug) + fprintf(stderr, "%s: absem does not exist\n", progname); + if(verbose) + printf("No Astribanks are initializing\n"); + return absem; + } + if(debug) + fprintf(stderr, "%s: absem exists\n", progname); + if(verbose) + printf("Astribanks are initializing...\n"); + return 0; +} + +int main(int argc, char *argv[]) +{ + const char options[] = "dvarwt:h"; + int val; + + progname = argv[0]; + while (1) { + int c; + int t; + + c = getopt (argc, argv, options); + if (c == -1) + break; + + switch (c) { + case 'd': + debug++; + break; + case 'v': + verbose++; + break; + case 't': + t = atoi(optarg); + if(t <= 0) { + fprintf(stderr, + "%s: -t expect a positive number of seconds: '%s'\n", + progname, optarg); + usage(); + } + timeout_seconds = t; + break; + case 'a': + if((val = absem_touch()) < 0) { + fprintf(stderr, "%s: Add failed: %d\n", progname, val); + return 1; + } + return 0; + case 'r': + if((val = absem_remove()) < 0) { + fprintf(stderr, "%s: Remove failed: %d\n", progname, val); + return 1; + } + return 0; + case 'w': + if((val = absem_wait()) < 0) { + fprintf(stderr, "%s: Wait failed: %d\n", progname, val); + return 1; + } + return 0; + case 'h': + default: + fprintf(stderr, "Unknown option '%c'\n", c); + usage(); + } + } + val = absem_detected(); + return (val == 0) ? 0 : 1; +} diff --git a/xpp/astribank_license.c b/xpp/astribank_license.c new file mode 100644 index 0000000..88d2af7 --- /dev/null +++ b/xpp/astribank_license.c @@ -0,0 +1,340 @@ +/* + * Written by Oron Peled + * Copyright (C) 2012, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include "astribank_license.h" + +#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) + +static const struct boundary { + const char *name; + const char *markers[2]; +} boundaries[] = { + [LICENSE_MARKER_NONE] = { /* Skip 0 */ + }, + [LICENSE_MARKER_XORCOM] = { + "Xorcom", + { + "-----BEGIN XORCOM LICENSE BLOCK-----", + "-----END XORCOM LICENSE BLOCK-----", + }, + }, + [LICENSE_MARKER_GENERIC] = { + "Generic", + { + "-----BEGIN TELEPHONY DEVICE LICENSE BLOCK-----", + "-----END TELEPHONY DEVICE LICENSE BLOCK-----", + } + }, +}; + +void license_markers_help(const char *prefix, FILE *fp) +{ + int i; + + fprintf(fp, "%sValid license markers:\n", prefix); + for (i = LICENSE_MARKER_NONE + 1; i < ARRAY_SIZE(boundaries); i++) { + const struct boundary *b = &boundaries[i]; + if (b->markers[0] != 0) + fprintf(fp, "%s\t%d - %s\n", prefix, i, b->name); + } +} + +int license_marker_valid(unsigned int which) +{ + if (which >= ARRAY_SIZE(boundaries)) + return 0; + if (boundaries[which].markers[0] == NULL) + return 0; + return 1; +} + +static const char *marker_string(unsigned int which, int end_marker) +{ + int selector = (end_marker) ? 1 : 0; + + if (license_marker_valid(which)) { + return boundaries[which].markers[selector]; + } + ERR("gen_marker: invalid marker %d\n", which); + return NULL; +} + +static int marker_find(const char *str, int end_marker) +{ + int selector = (end_marker) ? 1 : 0; + int i; + + for (i = LICENSE_MARKER_NONE + 1; i < ARRAY_SIZE(boundaries); i++) { + const struct boundary *b = &boundaries[i]; + const char *marker_str = b->markers[selector]; + +#if 0 + DBG("marker_find(%s,%d)[%d]: %s\n", + str, end_marker, i, marker_str); +#endif + if (!marker_str) + continue; + if (strcmp(str, marker_str) == 0) + return i; + } + return 0; +} + +static int bin_to_file(void *buf, int len, FILE *f) +{ + static int bytes_on_line; + unsigned char *p = buf; + if (buf == NULL) { + if (bytes_on_line != 0) { + if (fprintf(f, "\n") != 1) + return -1; + bytes_on_line = 0; + } + return 0; + } + int i; + for (i = 0; i < len; i++) { + if (fprintf(f, "%02x", *p++) != 2) + return -1; + bytes_on_line++; + if (bytes_on_line >= 16) { + if (fprintf(f, "\n") != 1) + return -1; + bytes_on_line = 0; + } + } + return 0; +} + +int write_to_file( + struct eeprom_table *eeprom_table, + struct capabilities *caps, + struct capkey *key, + unsigned int marker, + FILE *f) +{ + fprintf(f, "%s\n", marker_string(marker, 0)); + fprintf(f, "Version: 1.0\n"); + fprintf(f, "Timestamp: %u\n", caps->timestamp); + fprintf(f, "Serial: %.*s\n", LABEL_SIZE, eeprom_table->label); + fprintf(f, "Capabilities.Port.FXS: %d\n", caps->ports_fxs); + fprintf(f, "Capabilities.Port.FXO: %d\n", caps->ports_fxo); + fprintf(f, "Capabilities.Port.BRI: %d\n", caps->ports_bri); + fprintf(f, "Capabilities.Port.PRI: %d\n", caps->ports_pri); + fprintf(f, "Capabilities.Port.ECHO: %d\n", caps->ports_echo); + fprintf(f, "Capabilities.Twinstar: %d\n", CAP_EXTRA_TWINSTAR(caps)); + fprintf(f, "Data:\n"); + bin_to_file(eeprom_table, sizeof(*eeprom_table), f); + bin_to_file(caps, sizeof(*caps), f); + bin_to_file(key, sizeof(*key), f); + bin_to_file(NULL, 0, f); + fprintf(f, "%s\n", marker_string(marker, 1)); + return 0; +} + +/* + * Removes whitespace on both sizes of the string. + * Returns a pointer to the first non-space char. The string + * is modified in place to trim trailing whitespace. + * If the whole string is whitespace, returns NULL. + */ +static char *trim(char *s) +{ + int len = strlen(s); + while (len > 0 && isspace(s[len-1])) { + len--; + } + if (len == 0) + return NULL; + s[len] = '\0'; + while (isspace(*s)) + s++; + /* *s is not a space, since in this case we'd return NULL above */ + return s; +} + +static int get_key_value(char *line, char **key, char **value) +{ + char *p = strchr(line, ':'); + if (p == NULL) + return -1; + *p = '\0'; + *key = trim(line); + *value = trim(p + 1); + return 0; +} + +static int hex_digit_to_int(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + else if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + else + return -1; +} + +static int str_to_bin(char *line, void *buf, int maxlen) +{ + static int offset; + unsigned char *p = buf; + if (strlen(line) % 2 != 0) + return -1; + while (offset < maxlen && *line) { + uint8_t value; + char c = hex_digit_to_int(*line++); + if (c < 0 || *line == '\0') + return -1; + value = c << 4; + c = hex_digit_to_int(*line++); + if (c < 0) + return -1; + value |= c; + p[offset++] = value; + } + if (offset == maxlen && *line) + return -1; + return offset; +} + +int read_from_file( + struct eeprom_table *eeprom_table, + struct capabilities *caps, + struct capkey *capkey, + unsigned int *used_marker, + FILE *f) +{ + char buf[256]; + char *line, *key, *value; + int lineno = 0; + unsigned int license_marker_begin = 0; + unsigned int license_marker_end; + struct table { + struct eeprom_table eeprom_table; + struct capabilities capabilities; + struct capkey capkey; + } PACKED table; + enum PARSE_STATES { + STATE_BEFORE_LICENSE = 0, + STATE_EXPECT_VERSION = 1, + STATE_EXPECT_DATA = 2, + STATE_READ_DATA = 3, + STATE_AFTER_LICENSE = 4, + } state = STATE_BEFORE_LICENSE; + + memset(&table, 0, sizeof(struct table)); + /* + * states: + * 0: start - before BEGIN_LICENSE_BLOCK line. on BEGIN_LICENSE_BLOCK line goto 1. + * 1: read Version, goto 2. if not version line then error. + * 2: after BEGIN line. split line into key:value. if line is Data:, goto 3. + * 3: read binary data. if line is END_LICENSE_BLOCK goto 4. + * 4: END_LICENSE_BLOCK - ignore lines. + */ + while (fgets(buf, 256, f) != NULL) { + lineno++; + int len = strlen(buf); + if (len > 0 && buf[len-1] != '\n') { + ERR("Line %d: Line too long\n", lineno); + return -1; + } + line = trim(buf); + if (line == NULL) { + if (state > STATE_BEFORE_LICENSE && state < STATE_AFTER_LICENSE) { + ERR("Line %d: Empty line\n", lineno); + return -1; + } + else + continue; + } + switch (state) { + case STATE_BEFORE_LICENSE: + license_marker_begin = marker_find(line, 0); + if (license_marker_begin) + state = STATE_EXPECT_VERSION; + else { + ERR("Line %d: Invalid license begin block\n", lineno); + return -1; + } + break; + case STATE_EXPECT_VERSION: + if (get_key_value(line, &key, &value) < 0) { + ERR("Line %d: Can't parse line\n", lineno); + return -1; + } + if (strcmp(key, "Version") == 0) { + if (strcmp(value, "1.0") == 0) { + state = STATE_EXPECT_DATA; + } else { + ERR("Line %d: Unknown license file version '%s', need version '1.0'\n", lineno, value); + return -1; + } + } else { + ERR("Line %d: No license file version\n", lineno); + return -1; + } + break; + case STATE_EXPECT_DATA: + if (get_key_value(line, &key, &value) < 0) { + ERR("Line %d: Can't parse line\n", lineno); + return -1; + } + if (strcmp(key, "Data") == 0) { + state = STATE_READ_DATA; + break; + } + break; + case STATE_READ_DATA: + license_marker_end = marker_find(line, 1); + if (license_marker_end) { + if (license_marker_end != license_marker_begin) { + ERR("Line %d: End marker != Begin marker\n", lineno); + return -1; + } + state = STATE_AFTER_LICENSE; + break; + } + if (str_to_bin(line, &table, sizeof(table)) < 0) { + ERR("Line %d: Error in data block\n", lineno); + return -1; + } + break; + case STATE_AFTER_LICENSE: + break; + + } + } + if (state != STATE_AFTER_LICENSE) { + ERR("Invalid license file\n"); + return -1; + } + memcpy(eeprom_table, &table.eeprom_table, sizeof(*eeprom_table)); + memcpy(caps, &table.capabilities, sizeof(*caps)); + memcpy(capkey, &table.capkey, sizeof(*capkey)); + return 0; +} + diff --git a/xpp/astribank_license.h b/xpp/astribank_license.h new file mode 100644 index 0000000..74d6a31 --- /dev/null +++ b/xpp/astribank_license.h @@ -0,0 +1,29 @@ +#ifndef ASTRIBANK_ALLOW_H +#define ASTRIBANK_ALLOW_H + +#include "mpp.h" + +enum license_markers { + LICENSE_MARKER_NONE = 0, + LICENSE_MARKER_XORCOM = 1, + LICENSE_MARKER_GENERIC = 2, +}; + +int license_marker_valid(unsigned int which); +void license_markers_help(const char *prefix, FILE *fp); + +int write_to_file( + struct eeprom_table *eeprom_table, + struct capabilities *caps, + struct capkey *key, + unsigned int marker, + FILE *f); + +int read_from_file( + struct eeprom_table *eeprom_table, + struct capabilities *caps, + struct capkey *capkey, + unsigned int *used_marker, + FILE *f); + +#endif /* ASTRIBANK_ALLOW_H */ diff --git a/xpp/astribank_tool.8 b/xpp/astribank_tool.8 new file mode 100644 index 0000000..31f9564 --- /dev/null +++ b/xpp/astribank_tool.8 @@ -0,0 +1,86 @@ +.TH "ASTRIBANK_TOOL" "8" "29 March 2009" "" "" + +.SH NAME +astribank_tool \- Xorcom Astribank (xpp) control tool +.SH SYNOPSIS +.B astribank_tool [ options ] [ operation... ] \-D \fIdevice-path\fR + +.B astribank_tool [\-h] + +.SH DESCRIPTION +.B astribank_tool +is a tool to control the USB-level functionality of an Astribank. +The tool operates on a single Astribank at a time (given as parameter +to the \-D command line option). + +.SH OPTIONS +.B \-D +.I device-path +.RS +Required. The device to read from/write to. This is +\fIbus_num\fR/\fIdevice_num\fR, where \fIbus_num\fR and \fIdevice_num\fR +are the first two numbers in the output of lsusb(8) or dahdi_hardware(8). +On older versions of this tool you needed a complete path to the device, +which would be /dev/bus/usb/\fIbus_num\fR/\fIdevice_num\fR, or +/proc/bus/usb/\fIbus_num\fR/\fIdevice_num\fR. +.RE + +.B \-p \fInum\fR +.RS +Set the TwinStar port number. Either 0 or 1. + +(TODO: explain). +.RE + +.B \-r \fItype\fR +.RS +Reset the Astribank and renumerate its USB connection to power on product ID. + +Tyep can be: \fBhalf\fR or \fBfull\fR. + +(TODO: explain those). +.RE + +.B \-w 0|1 +.RS +Enable (1) or disable (0) the TwinStar watchdog. When enabled, the +Astribank will jump to the second port if this system is "not working" +and the system on the second port is available. +.RE + +.B \-Q +.RS +Query astribank properties via MPP protocol. +.RE + +.B \-n +.RS +Renumerate the Astribank product number (e.g: from 1161 to 1162). +.RE + +.B \-v +.RS +Increase verbosity. May be used multiple times. +.RE + +.B \-d \fImask\fR +.RS +Set debug mask to \fImask\fR. Default is 0, 0xFF is "everything". +.RE + +.B \-h +.RS +Displays usage message. +.RE + +.SH SEE ALSO +fxload(8), lsusb(8), astribank_hexload(8) + +.SH AUTHOR +This manual page was written by Tzafrir Cohen . +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common\-licenses/GPL. diff --git a/xpp/astribank_tool.c b/xpp/astribank_tool.c new file mode 100644 index 0000000..f3ca976 --- /dev/null +++ b/xpp/astribank_tool.c @@ -0,0 +1,287 @@ +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "astribank_usb.h" +#include "mpptalk.h" +#include +#include + +#define DBG_MASK 0x80 +/* if enabled, adds support for resetting pre-MPP USB firmware - if we + * failed opening a device and we were asked to reset it, try also the + * old protocol. + */ +#define SUPPORT_OLD_RESET + +static char *progname; + +static void usage() +{ + fprintf(stderr, "Usage: %s [options] -D {/proc/bus/usb|/dev/bus/usb}// [operation...]\n", progname); + fprintf(stderr, "\tOptions:\n"); + fprintf(stderr, "\t\t[-v] # Increase verbosity\n"); + fprintf(stderr, "\t\t[-d mask] # Debug mask (0xFF for everything)\n"); + fprintf(stderr, "\tOperations:\n"); + fprintf(stderr, "\t\t[-n] # Renumerate device\n"); + fprintf(stderr, "\t\t[-r kind] # Reset: kind = {half|full}\n"); + fprintf(stderr, "\t\t[-p port] # TwinStar: USB port number [0, 1]\n"); + fprintf(stderr, "\t\t[-w (0|1)] # TwinStar: Watchdog off or on guard\n"); + fprintf(stderr, "\t\t[-Q] # Query device properties\n"); + exit(1); +} + +static int reset_kind(const char *arg) +{ + static const struct { + const char *name; + int type_code; + } reset_kinds[] = { + { "half", 0 }, + { "full", 1 }, + }; + int i; + + for(i = 0; i < sizeof(reset_kinds)/sizeof(reset_kinds[0]); i++) { + if(strcasecmp(reset_kinds[i].name, arg) == 0) + return reset_kinds[i].type_code; + } + ERR("Uknown reset kind '%s'\n", arg); + return -1; +} + + +static int show_hardware(struct astribank_device *astribank) +{ + int ret; + struct eeprom_table eeprom_table; + struct capabilities capabilities; + struct extrainfo extrainfo; + + ret = mpp_caps_get(astribank, &eeprom_table, &capabilities, NULL); + if(ret < 0) + return ret; + show_eeprom(&eeprom_table, stdout); + show_astribank_status(astribank, stdout); + if(astribank->eeprom_type == EEPROM_TYPE_LARGE) { + show_capabilities(&capabilities, stdout); + if(STATUS_FPGA_LOADED(astribank->status)) { + uint8_t unit; + uint8_t card_status; + uint8_t card_type; + uint8_t fpga_configuration; + uint8_t status; + + for(unit = 0; unit < 5; unit++) { + ret = mpps_card_info(astribank, unit, &card_type, &card_status); + if(ret < 0) + return ret; + printf("CARD %d: type=%x.%x %s\n", unit, + ((card_type >> 4) & 0xF), (card_type & 0xF), + ((card_status & 0x1) ? "PIC" : "NOPIC")); + } + ret = mpps_stat(astribank, unit, &fpga_configuration, &status); + if (ret < 0) + return ret; + printf("FPGA: %-17s: %d\n", "Configuration num", fpga_configuration); + printf("FPGA: %-17s: %s\n", "Watchdog Timer", + (SER_STAT_WATCHDOG_READY(status)) ? "ready" : "expired"); + printf("FPGA: %-17s: %s\n", "XPD Alive", + (SER_STAT_XPD_ALIVE(status)) ? "yes" : "no"); + } + ret = mpp_extrainfo_get(astribank, &extrainfo); + if(ret < 0) + return ret; + show_extrainfo(&extrainfo, stdout); + if(CAP_EXTRA_TWINSTAR(&capabilities)) { + twinstar_show(astribank, stdout); + } + } + return 0; +} + +#ifdef SUPPORT_OLD_RESET +/* Try to reset a device using USB_FW.hex, up to Xorcom rev. 6885 */ +int old_reset(const char* devpath) +{ + struct astribank_device *astribank; + int ret; + struct { + uint8_t op; + } PACKED header = {0x20}; /* PT_RESET */ + char *buf = (char*) &header; + + /* Note that the function re-opens the connection to the Astribank + * as any reference to the previous connection was lost when mpp_open + * returned NULL as the astribank reference. */ + astribank = astribank_open(devpath, 1); + if (!astribank) { + DBG("Failed re-opening astribank device for old_reset\n"); + return -ENODEV; + } + ret = xusb_send(astribank->xusb, buf, 1, 5000); + + /* If we just had a reenumeration, we may get -ENODEV */ + if(ret < 0 && ret != -ENODEV) + return ret; + /* We don't astribank_close(), as it has likely been + * reenumerated by now. */ + return 0; +} +#endif /* SUPPORT_OLD_RESET */ + +int main(int argc, char *argv[]) +{ + char *devpath = NULL; + struct astribank_device *astribank; + const char options[] = "vd:D:nr:p:w:Q"; + int opt_renumerate = 0; + char *opt_port = NULL; + char *opt_watchdog = NULL; + char *opt_reset = NULL; + int opt_query = 0; + int ret; + + progname = argv[0]; + while (1) { + int c; + + c = getopt (argc, argv, options); + if (c == -1) + break; + + switch (c) { + case 'D': + devpath = optarg; + break; + case 'n': + opt_renumerate++; + break; + case 'p': + opt_port = optarg; + break; + case 'w': + opt_watchdog = optarg; + break; + case 'r': + opt_reset = optarg; + /* + * Sanity check so we can reject bad + * arguments before device access. + */ + if(reset_kind(opt_reset) < 0) + usage(); + break; + case 'Q': + opt_query = 1; + break; + case 'v': + verbose++; + break; + case 'd': + debug_mask = strtoul(optarg, NULL, 0); + break; + case 'h': + default: + ERR("Unknown option '%c'\n", c); + usage(); + } + } + if(!devpath) { + ERR("Missing device path\n"); + usage(); + } + DBG("Startup %s\n", devpath); + if((astribank = mpp_init(devpath, 1)) == NULL) { + ERR("Failed initializing MPP\n"); +#ifdef SUPPORT_OLD_RESET + DBG("opt_reset = %s\n", opt_reset); + if (opt_reset) { + DBG("Trying old reset method\n"); + if ((ret = old_reset(devpath)) != 0) { + ERR("Old reset method failed as well: %d\n", ret); + } + } +#endif /* SUPPORT_OLD_RESET */ + + return 1; + } + /* + * First process reset options. We want to be able + * to reset minimal USB firmwares even if they don't + * implement the full MPP protocol (e.g: EEPROM_BURN) + */ + if(opt_reset) { + int full_reset; + + if((full_reset = reset_kind(opt_reset)) < 0) { + ERR("Bad reset kind '%s'\n", opt_reset); + return 1; + } + DBG("Reseting (%s)\n", opt_reset); + if((ret = mpp_reset(astribank, full_reset)) < 0) { + ERR("%s Reseting astribank failed: %d\n", + (full_reset) ? "Full" : "Half", ret); + } + goto out; + } + show_astribank_info(astribank); + if(opt_query) { + show_hardware(astribank); + } else if(opt_renumerate) { + DBG("Renumerate\n"); + if((ret = mpp_renumerate(astribank)) < 0) { + ERR("Renumerating astribank failed: %d\n", ret); + } + } else if(opt_watchdog) { + int watchdogstate = strtoul(opt_watchdog, NULL, 0); + + DBG("TWINSTAR: Setting watchdog %s-guard\n", + (watchdogstate) ? "on" : "off"); + if((ret = mpp_tws_setwatchdog(astribank, watchdogstate)) < 0) { + ERR("Failed to set watchdog to %d\n", watchdogstate); + return 1; + } + } else if(opt_port) { + int new_portnum = strtoul(opt_port, NULL, 0); + int tws_portnum = mpp_tws_portnum(astribank); + char *msg = (new_portnum == tws_portnum) + ? " Same same, never mind..." + : ""; + + DBG("TWINSTAR: Setting portnum to %d.%s\n", new_portnum, msg); + if((ret = mpp_tws_setportnum(astribank, new_portnum)) < 0) { + ERR("Failed to set USB portnum to %d\n", new_portnum); + return 1; + } + } +out: + mpp_exit(astribank); + return 0; +} diff --git a/xpp/astribank_upgrade b/xpp/astribank_upgrade new file mode 100755 index 0000000..71ae238 --- /dev/null +++ b/xpp/astribank_upgrade @@ -0,0 +1,150 @@ +#!/bin/bash + +# astribank_upgrade: force load Xorcom Astribank (XPP) USB firmware +# A reduced version of xpp_fxloader for manual upgrades. +# +# Written by Oron Peled +# Copyright (C) 2009 Xorcom +# +# All rights reserved. +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +set -e + +# Make sure fxload is in the path: +PATH="$PATH:/usr/local/sbin:/sbin:/usr/sbin" +export PATH + +me=`basename $0` + +if [ -t 2 ]; then + LOGGER="logger -i -t '$me' -s" +else + LOGGER="logger -i -t '$me'" +fi + +USBFS_PREFIX=/proc/bus/usb +DEVUSB_PREFIX=/dev/bus/usb +USB_PREFIX= + +USB_FW="${USB_FW:-USB_FW.hex}" + +if [ "$USB_PREFIX" = '' ]; then + if [ -d "$DEVUSB_PREFIX" ]; then + USB_PREFIX=$DEVUSB_PREFIX + elif [ -r "$USBFS_PREFIX/devices" ]; then + USB_PREFIX=$USBFS_PREFIX + fi +fi + +# With Kernels older that 2.6.10 it seems to be possible +# to trigger a race condition by running fxload or fpga_load +# immediately after the detection of the device. +KERNEL_HAS_USB_RACE=0 +case "`uname -r`" in 2.6.[89]*) KERNEL_HAS_USB_RACE=1;; esac +sleep_if_race() { + if [ "$KERNEL_HAS_USB_RACE" = '1' ]; then + sleep 2 + fi +} + +find_dev() { + v_id=$1 + p_id=$2 + + lsusb | tr -d : | awk "/ ID $v_id$p_id/{printf \"$USB_PREFIX/%s/%s \",\$2,\$4}" +} + +run_fxload() { + sleep_if_race + fxload -t fx2 $* 2>&1 1>/dev/null | $LOGGER + status=$PIPESTATUS + if [ $status != 0 ]; then + $LOGGER "fxload failed with status $status" + exit 55 + fi +} + +load_usb_fw() { + v_id=$1 + p_id=$2 + fw=$3 + + devices=`find_dev $v_id $p_id` + for dev in $devices + do + ver=$(awk '/\$Id:/ { print $4 }' $FIRMWARE_DIR/$fw) + $LOGGER "USB Firmware $FIRMWARE_DIR/$fw (Version=$ver) into $dev" + run_fxload -D $dev -I $FIRMWARE_DIR/$fw || exit 1 + done +} + +numdevs() { + v_ids="$1" + p_ids="$2" + + for v in $v_ids + do + ( + for p in $p_ids + do + find_dev $v $p + done + ) + done | wc -w +} + +wait_renumeration() { + num="$1" + v_ids="$2" + p_ids="$3" + + while + n=`numdevs "$v_ids" "$p_ids"` + [ "$num" -gt "$n" ] + do + echo -n "." + sleep 1 + done + echo "Got all $num devices" +} + +if [ "$#" -ne 1 ]; then + echo >&2 "Usage: $0 " + exit 1 +fi +FIRMWARE_DIR="$1" +[ -f "$FIRMWARE_DIR/$USB_FW" ] || { + echo >&2 "$0: Could not find '$FIRMWARE_DIR/$USB_FW'" + exit 1 +} +numdevs=`numdevs e4e4 '11[3456][01]'` +$LOGGER -- "--------- LOADING NEW USB FIRMWARE: ($1) [$numdevs devices]" +load_usb_fw e4e4 1130 $USB_FW +load_usb_fw e4e4 1140 $USB_FW +load_usb_fw e4e4 1150 $USB_FW +load_usb_fw e4e4 1160 $USB_FW +load_usb_fw e4e4 1131 $USB_FW +load_usb_fw e4e4 1141 $USB_FW +load_usb_fw e4e4 1151 $USB_FW +load_usb_fw e4e4 1161 $USB_FW +load_usb_fw e4e4 1132 $USB_FW +load_usb_fw e4e4 1142 $USB_FW +load_usb_fw e4e4 1152 $USB_FW +load_usb_fw e4e4 1162 $USB_FW +wait_renumeration $numdevs e4e4 '11[3456]1' +$LOGGER -- "--------- NEW USB FIRMWARE IS LOADED" diff --git a/xpp/astribank_usb.c b/xpp/astribank_usb.c new file mode 100644 index 0000000..af7e6aa --- /dev/null +++ b/xpp/astribank_usb.c @@ -0,0 +1,276 @@ +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#define _GNU_SOURCE /* for memrchr() */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "astribank_usb.h" +#include + +static const char rcsid[] = "$Id$"; + +#define DBG_MASK 0x01 +#define TIMEOUT 500 + +#define TYPE_ENTRY(t,p,ni,n,ne,out,in,...) \ + { \ + .my_vendor_id = 0xe4e4, \ + .my_product_id = (p), \ + .name = #t, \ + .num_interfaces = (ni), \ + .my_interface_num = (n), \ + .num_endpoints = (ne), \ + .my_ep_in = (in), \ + .my_ep_out = (out), \ + } + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +static const struct xusb_spec astribank_specs[] = { + /* OLD Firmwares */ + TYPE_ENTRY("USB-OLDFXS", 0x1131, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("FPGA-OLDFXS", 0x1132, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("USB-BRI", 0x1141, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("FPGA-BRI", 0x1142, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("USB-OLD", 0x1151, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("FPGA-OLD", 0x1152, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + + TYPE_ENTRY("USB-MULTI", 0x1161, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("FPGA-MULTI", 0x1162, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("BURNED-MULTI", 0x1164, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("USB-BURN", 0x1112, 2, 1, 2, MP_EP_OUT, MP_EP_IN), +}; + +static const struct xusb_spec astribank_pic_specs[] = { + TYPE_ENTRY("USB_PIC", 0x1161, 2, 0, 2, XPP_EP_OUT, XPP_EP_IN), +}; +#undef TYPE_ENTRY + +//static int verbose = LOG_DEBUG; + +/* + * USB handling + */ +struct astribank_device *astribank_open(const char devpath[], int iface_num) +{ + struct astribank_device *astribank = NULL; + struct xusb *xusb; + + DBG("devpath='%s' iface_num=%d\n", devpath, iface_num); + if((astribank = malloc(sizeof(struct astribank_device))) == NULL) { + ERR("Out of memory\n"); + goto fail; + } + memset(astribank, 0, sizeof(*astribank)); + if (iface_num) { + xusb = xusb_find_bypath(astribank_specs, ARRAY_SIZE(astribank_specs), devpath); + } else { + xusb = xusb_find_bypath(astribank_pic_specs, ARRAY_SIZE(astribank_pic_specs), devpath); + } + if (!xusb) { + ERR("%s: No device found\n", __func__); + goto fail; + } + astribank->xusb = xusb; + astribank->is_usb2 = (xusb_packet_size(xusb) == 512); + astribank->my_interface_num = iface_num; + if (xusb_claim_interface(astribank->xusb) < 0) { + ERR("xusb_claim_interface failed\n"); + goto fail; + } + astribank->tx_sequenceno = 1; + return astribank; +fail: + if (astribank) { + free(astribank); + astribank = NULL; + } + return NULL; +} + +/* + * MP device handling + */ +void show_astribank_info(const struct astribank_device *astribank) +{ + struct xusb *xusb; + + assert(astribank != NULL); + xusb = astribank->xusb; + assert(xusb != NULL); + if(verbose <= LOG_INFO) { + xusb_showinfo(xusb); + } else { + const struct xusb_spec *spec; + + spec = xusb_spec(xusb); + printf("USB Bus/Device: [%s]\n", xusb_devpath(xusb)); + printf("USB Firmware Type: [%s]\n", spec->name); + printf("USB iSerialNumber: [%s]\n", xusb_serial(xusb)); + printf("USB iManufacturer: [%s]\n", xusb_manufacturer(xusb)); + printf("USB iProduct: [%s]\n", xusb_product(xusb)); + } +} + +void astribank_close(struct astribank_device *astribank, int disconnected) +{ + assert(astribank != NULL); + if (astribank->xusb) { + xusb_close(astribank->xusb); + astribank->xusb = NULL; + } + astribank->tx_sequenceno = 0; +} + +#if 0 +int flush_read(struct astribank_device *astribank) +{ + char tmpbuf[BUFSIZ]; + int ret; + + DBG("starting...\n"); + memset(tmpbuf, 0, BUFSIZ); + ret = recv_usb(astribank, tmpbuf, BUFSIZ, 1); + if(ret < 0 && ret != -ETIMEDOUT) { + ERR("ret=%d\n", ret); + return ret; + } else if(ret > 0) { + DBG("Got %d bytes:\n", ret); + dump_packet(LOG_DEBUG, DBG_MASK, __FUNCTION__, tmpbuf, ret); + } + return 0; +} +#endif + + +int release_isvalid(uint16_t release) +{ + uint8_t rmajor = (release >> 8) & 0xFF; + uint8_t rminor = release & 0xFF; + + return (rmajor > 0) && + (rmajor < 10) && + (rminor > 0) && + (rminor < 10); +} + +int label_isvalid(const char *label) +{ + int len; + int goodlen; + const char GOOD_CHARS[] = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" + "-_."; + + len = strlen(label); + goodlen = strspn(label, GOOD_CHARS); + if(len > LABEL_SIZE) { + ERR("Label too long (%d > %d)\n", len, LABEL_SIZE); + return 0; + } + if(goodlen != len) { + ERR("Bad character in label (pos=%d)\n", goodlen); + return 0; + } + return 1; +} + +int eeprom_fill(struct eeprom_table *eprm, + const char *vendor, + const char *product, + const char *release, + const char *label) +{ + uint16_t val; + + eprm->source = 0xC0; + eprm->config_byte = 0; + if(vendor) { + val = strtoul(vendor, NULL, 0); + if(!val) { + ERR("Invalid vendor '%s'\n", + vendor); + return -EINVAL; + } + eprm->vendor = val; + } + if(product) { + val = strtoul(product, NULL, 0); + if(!val) { + ERR("Invalid product '%s'\n", + product); + return -EINVAL; + } + eprm->product = val; + } + if(release) { + int release_major = 0; + int release_minor = 0; + uint16_t value; + + if(sscanf(release, "%d.%d", &release_major, &release_minor) != 2) { + ERR("Failed to parse release number '%s'\n", release); + return -EINVAL; + } + value = (release_major << 8) | release_minor; + DBG("Parsed release(%d): major=%d, minor=%d\n", + value, release_major, release_minor); + if(!release_isvalid(value)) { + ERR("Invalid release number 0x%X\n", value); + return -EINVAL; + } + eprm->release = value; + } + if(label) { + /* padding */ + if(!label_isvalid(label)) { + ERR("Invalid label '%s'\n", label); + return -EINVAL; + } + memset(eprm->label, 0, LABEL_SIZE); + memcpy(eprm->label, label, strlen(label)); + } + return 0; +} + +int astribank_has_twinstar(struct astribank_device *astribank) +{ + uint16_t product_series; + + assert(astribank != NULL); + product_series = xusb_product_id(astribank->xusb); + product_series &= 0xFFF0; + if(product_series == 0x1160) /* New boards */ + return 1; + return 0; +} + diff --git a/xpp/astribank_usb.h b/xpp/astribank_usb.h new file mode 100644 index 0000000..69778e6 --- /dev/null +++ b/xpp/astribank_usb.h @@ -0,0 +1,113 @@ +#ifndef ASTRIBANK_USB_H +#define ASTRIBANK_USB_H +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include "mpp.h" + +/* + * Astribank handling + */ + +#define PACKET_SIZE 512 + +/* USB Endpoints */ +#define MP_EP_OUT 0x04 /* Managment processor */ +#define MP_EP_IN 0x88 /* Managment processor */ + +#define XPP_EP_OUT 0x02 /* XPP */ +#define XPP_EP_IN 0x86 /* XPP */ + +/* USB firmware types */ +#define USB_11xx 0 +#define USB_FIRMWARE_II 1 +#define USB_PIC 2 + +struct interface_type { + int type_code; + int num_interfaces; + int my_interface_num; + int num_endpoints; + int my_ep_out; + int my_ep_in; + char *name; + int endpoints[4]; /* for matching */ +}; + +enum eeprom_burn_state { + BURN_STATE_NONE = 0, + BURN_STATE_STARTED = 1, + BURN_STATE_ENDED = 2, + BURN_STATE_FAILED = 3, +}; + +struct astribank_device { + struct xusb *xusb; + struct xtalk_device *xtalk_dev; + usb_dev_handle *handle; + int my_interface_num; + int my_ep_out; + int my_ep_in; + char iInterface[BUFSIZ]; + int is_usb2; + enum eeprom_type eeprom_type; + enum eeprom_burn_state burn_state; + uint8_t status; + uint8_t mpp_proto_version; + struct eeprom_table *eeprom; + struct firmware_versions fw_versions; + uint16_t tx_sequenceno; +}; + +/* + * Prototypes + */ +struct astribank_device *astribank_open(const char devpath[], int iface_num); +void astribank_close(struct astribank_device *astribank, int disconnected); +void show_astribank_info(const struct astribank_device *astribank); +int send_usb(struct astribank_device *astribank, char *buf, int len, int timeout); +int recv_usb(struct astribank_device *astribank, char *buf, size_t len, int timeout); +int flush_read(struct astribank_device *astribank); +int eeprom_fill(struct eeprom_table *eprm, + const char *vendor, + const char *product, + const char *release, + const char *label); +int astribank_has_twinstar(struct astribank_device *astribank); +int label_isvalid(const char *label); + +#define AB_REPORT(report_type, astribank, fmt, ...) \ + report_type("%s [%s]: " fmt, \ + xusb_devpath((astribank)->xusb), \ + xusb_serial((astribank)->xusb), \ + ## __VA_ARGS__) + +#define AB_INFO(astribank, fmt, ...) \ + AB_REPORT(INFO, astribank, fmt, ## __VA_ARGS__) + +#define AB_ERR(astribank, fmt, ...) \ + AB_REPORT(ERR, astribank, fmt, ## __VA_ARGS__) + +#endif /* ASTRIBANK_USB_H */ diff --git a/xpp/dahdi.cgi b/xpp/dahdi.cgi new file mode 100755 index 0000000..5b0e591 --- /dev/null +++ b/xpp/dahdi.cgi @@ -0,0 +1,265 @@ +#! /usr/bin/perl -wT + +# Written by Tzafrir Cohen +# Copyright (C) 2008, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. + +use strict; +use File::Basename; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); } + +use CGI::Pretty qw/:standard start_ul start_li start_div start_pre/; +use Dahdi; +use Dahdi::Xpp; +use Dahdi::Hardware; + +$ENV{'PATH'} = '/bin:/usr/bin'; + +my $DEF_TOK = ''; + +my $style=< +END + +my @Toc = (); + +sub header_line($$) { + my ($text, $anchor) = @_; + print a({-name=>$anchor},h2($text)); + push(@Toc, [$text, $anchor] ); +} + +print header, + start_html( + -title=>"DAHDI Information", + -style=>{-code=>$style}), + h1("DAHDI Information"); + +print start_div({-id=>'content'}); + +sub dahdi_spans() { + my %ChansStat = (num=>0, configured=>0, inuse=>0); + + header_line("DAHDI Spans", 'spans'); + + print p('Here we list the ', + dfn({-title=> 'A span is a logical unit of dahdi + channels. e.g.: all the channels that come from + a specific port, or all the analog channels from + a certain PCI card'}, + 'spans'), + ' that DAHDI devices registered + with DAHDI. For each span we list all of its channels.' + ), + p('A channel that appears in ', + span({-class=>'status-noconf'},'red text'),' ', + 'is one that has not been configured at all. Either not + listed in system.conf, or dahdi_cfg was not run.' + ), + p('A channel that appears in ', + span({-class=>'status-notused'},'pink text'),' ', + 'is one that has been configured but is not used by any + application. This usually means that either Asterisk is + not running or Asterisk is not configured to use this + channel' + ), + p('If a port is disconnected it will have a "RED" alarm. + For a FXO port this will only be on the specific port. + For a BRI, E1 or T1 port it will be an alarm on the apn + and all of the channels.'), + ; + + + + foreach my $span (Dahdi::spans()) { + my $spanno = $span->num; + my $index = 0; + + print h3(a({-name=>"zap_span_$spanno"}, "Span $spanno: ", + $span->name, " ", $span->description)), + start_ul; + foreach my $chan ($span->chans()) { + my $batt = ''; + $batt = "(battery)" if $chan->battery; + my $type = $chan->type; + my $sig = $chan->signalling; + my $info = $chan->info; + my $chan_stat = 'ok'; + $ChansStat{num}++; + if (!$sig) { + $chan_stat = 'noconf'; + } else { + $ChansStat{configured}++; + if ($info =~ /\(In use\)/) { + $ChansStat{inuse}++; + } else { + $chan_stat = 'notused'; + } + } + # TODO: color differently if no signalling and + # if not in-use and in alarm. + print li({-class=>"status-$chan_stat"}, + $chan->num, " $type, $sig $info $batt"); + } + print end_ul; + } +} + +sub dahdi_hardware() { + header_line("DAHDI Hardware", 'zap_hard'); + + print p('Here we list all the DAHDI hardware devices on your + system. If a device is not currently handled by a + driver, it will appear as ', + span({-class=>'status-noconf'},'red text'),'.'); + + my $hardware = Dahdi::Hardware->scan; + + print start_ul; + foreach my $device ($hardware->device_list) { + my $driver = $device->driver || ""; + my $status = 'ok'; + + if (! $device->loaded) { + $status = 'noconf'; + } + + print li({-class=>"status-$status"}, + $device->hardware_name, ": ", $driver, + " [".$device->vendor,"/". $device->product. "] ", + $device->description); + } + print end_ul; +} + +sub astribanks() { + header_line("Astribanks", 'astribanks'); + + print p('Here we list all the Astribank devices (That are + handled by the drivers). For each Astribank we list + its XPDs. A ', + dfn({-title=> + 'a logical unit of the Astribank. It will '. + 'be registered in DAHDI as a single span. This '. + 'can be either an analog (FXS or FXO) module or '. + 'a single port in case of a BRI and PRI modules.' + }, + 'XPD'),'. ', + ' that is registered will have a link to the + information about the span below. One that is not + registered will appear as ', + span({-class=>'status-noconf'},'red text'),'.'); + + print start_ul; + + foreach my $xbus (Dahdi::Xpp::xbuses()) { + print start_li, + $xbus->name." (".$xbus->label .", ".$xbus->connector .")", + start_ul; + foreach my $xpd ($xbus->xpds) { + my $chan_stat = 'ok'; + my $span_str = 'UNREGISTERED'; + if ($xpd->spanno) { + my $spanno = $xpd->spanno; + $span_str = + a({-href=>"#zap_span_$spanno"}, + "Span $spanno"); + } else { + $chan_stat = 'noconf'; + } + print li({-class=>"status-$chan_stat"}, + '[', $xpd->type, '] ', $span_str, $xpd->fqn + ); + } + print end_ul, end_li; + } + print end_ul; +} + + +dahdi_hardware(); + +astribanks(); + +dahdi_spans(); + +print end_div(); # content + +print div({-id=>'toc'}, + p( a{-href=>'/'},'[Homepage]' ), + ( map {p( a({-href=> '#'.$_->[1]},$_->[0] ) )} @Toc ), +); diff --git a/xpp/dahdi_drivers b/xpp/dahdi_drivers new file mode 100755 index 0000000..863d7b1 --- /dev/null +++ b/xpp/dahdi_drivers @@ -0,0 +1,23 @@ +#! /usr/bin/perl -w +use strict; +use File::Basename; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); } + +use Dahdi::Hardware; + +my @drivers = Dahdi::Hardware->drivers; +print join("\n", @drivers),"\n"; +__END__ + +=head1 NAME + +dahdi_drivers - Show drivers required for installed dahdi devices. + +=head1 SYNOPSIS + +dahdi_drivers + +=head1 DESCRIPTION + +This script shows by default the list of drivers required for currently +installed dahdi devices. diff --git a/xpp/dahdi_genconf b/xpp/dahdi_genconf new file mode 100755 index 0000000..842084d --- /dev/null +++ b/xpp/dahdi_genconf @@ -0,0 +1,241 @@ +#! /usr/bin/perl -w +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use File::Basename; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); } + +use Getopt::Long; +use Dahdi; +use Dahdi::Xpp; +use Dahdi::Config::Gen; +use Dahdi::Config::Params; + +Getopt::Long::Configure ("bundling"); + +my $version = '1'; # Functionality version (integer) +my $revision = '$Revision$'; + +my %opts; + +sub usage { + warn "Usage: $0 [options] \n"; + warn " Options:\n"; + warn " --line-mode= - Also generate span-types.conf with default line mode\n"; + warn " -F|--freepbx - Modify configuration for Freepbx (skip FXS channels)\n"; + warn " -v|--verbose - Be versbose, show generated files\n"; + warn " -V|--version - Show version and exit\n"; + warn " -h|--help - Show this message\n"; + exit 1; +} + +sub set_defaults { + my $default_file = $ENV{GENCONF_PARAMETERS} || "/etc/dahdi/genconf_parameters"; + my $params = Dahdi::Config::Params->new($default_file); + #$params->dump; + if($opts{v}) { + print "Default parameters from ", $params->{GENCONF_FILE}, "\n"; + } + my $gconfig = Dahdi::Config::Gen->new($params); + #$gconfig->dump; + return $gconfig; +} + +sub spans_prep($@) { + my $gconfig = shift || die; + my @spans = @_; + foreach my $span (@spans) { + if($span->is_pri || $span->is_bri) { + $span->pri_set_fromconfig($gconfig); + } + } +} + +sub munge_spantypes { + if ($opts{'line-mode'}) { + print "Will generate span-types.conf with line-mode=$opts{'line-mode'}\n" + if $opts{'verbose'}; + return "spantypes=line-mode=$opts{'line-mode'}"; + } else { + print "Will generate span-types.conf\n" if $opts{'verbose'}; + return "spantypes"; + } +} + +sub generator_list($) { + my $gconfig = shift || die; + my @genlist; + + if (@ARGV) { + for my $gen (@ARGV) { + $gen = munge_spantypes() if $gen eq 'spantypes'; + push @genlist, $gen; + } + } else { + # No files given. Use the defaults. + @genlist = ('assignedspans', 'system', 'chandahdi'); + if($gconfig->{'pri_connection_type'} eq 'R2') { + push @genlist, 'unicall'; + } + push(@genlist, munge_spantypes()) if $opts{'line-mode'}; + } + return @genlist; +} + +sub parse_genopts($) { + my $optstr = shift; + my %genopts; + + $optstr = '' unless defined $optstr; + foreach my $o (split(/,/, $optstr)) { + my ($k, $v) = split(/=/, $o, 2); + $v = 1 unless defined $v and $v; + $genopts{$k} = $v; + } + return %genopts; +} + +sub generate_files($@) { + my $gconfig = shift || die; + my @spans = @_; + my @generators = generator_list($gconfig); + + for my $gen (@generators) { + my ($name, $optstr) = split(/=/, $gen, 2); + die "Illegal name '$name'\n" unless $name =~ /^\w+$/; + $name =~ s/(.)(.*)/\u$1\L$2/; + my %genopts = parse_genopts($optstr); + $genopts{'freepbx'} = 'yes' if $opts{'F'}; + if(defined $opts{'v'}) { + $genopts{'verbose'} = $opts{v}; + } + $gconfig->run_generator($name, \%genopts, @spans); + } +} + +GetOptions(\%opts, + "line-mode=s", + "h|help", + "v|verbose", + "V|version", + "F|freepbx", + ) or usage; + +usage if $opts{h}; + +if($opts{'V'}) { + my $revstr = $revision; + $revstr =~ s/[^$]*\$[^:]+:\s*//; + $revstr =~ s/\s*\$.*//; + print "$0: version=$version revision=$revstr\n"; + exit 0; +} + +my $gconfig = set_defaults; +my @spans = Dahdi::spans(); +spans_prep($gconfig, @spans); +generate_files($gconfig, @spans); + +__END__ + +=head1 NAME + +dahdi_genconf - Generate configuration for Dahdi channels. + +=head1 SYNOPSIS + +dahdi_genconf [options] [generator...] + +=head1 DESCRIPTION + +This script generate configuration files for Dahdi hardware. +It uses two information sources: + +=over 4 + +=item Hardware + + The actual Dahdi hardware is automatically detected on the host. + +=item /etc/dahdi/genconf_parameters + +A configuration file that supplements the hardware information. +Its location may be overridden via the C environment +variable. + +=back + +The dahdi_genconf script can generate various kinds of configuration files +as specified by the generator arguments. Each generator is a perl class +in Dahdi::Config::Gen namespace. The generator names on the command line +are the class names in lowercase. + +The following generators are currently implemented: system, modules, spantypes, +assignedspans, chandahdi, unicall, users. + +For further documentation on each, please user perldoc on the relevant +class. E.g: C + +Each generator on the command line may be passed custom options by assigning +a comma separated list of options to the generator name. E.g: + + dahdi_genconf system chandahdi=verbose unicall + +=head2 Global options: + +=over 4 + +=item -V --version + +Version -- print version string and exit. + +=item -v --verbose + +Verbose -- sets the C<'verbose'> option for all generators. + +=item -F --freepbx + +Freepbx -- sets the C<'freepbx'> option for all generators. +Currently, chandahdi is affected. + +=item --line-mode=I + +I may be E1, J1 or T1. + +Enables the generator B and the option B to it. +(Equivalent to the option C<--line-mode> to C). This +will generate a C file with a single wildcard line +setting the line mode to I. + +=back + +=head2 Implementation notes: + +=over 4 + +=item * + +F parsing is done via C. +An object representing the parsed data is instantiated by: +Cnew()>. +The C method of this object contains all the hard coded +defaults of the configuration directives. + +=item * + +A configuration object is instantiated by Cnew($params)>. +The mapping of configuration directives into semantic configuration is +done in the constructor. + +=item * + +A single generator is run via the the C method of the +configuration object. + +=back diff --git a/xpp/dahdi_hardware b/xpp/dahdi_hardware new file mode 100755 index 0000000..032b9e3 --- /dev/null +++ b/xpp/dahdi_hardware @@ -0,0 +1,196 @@ +#! /usr/bin/perl -w +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use File::Basename; +use Getopt::Std; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); } + +use Dahdi; +use Dahdi::Span; +use Dahdi::Xpp; +use Dahdi::Xpp::Xbus; +use Dahdi::Hardware; +use Dahdi::Xpp::Mpp; + +sub usage { + die "Usage: $0 [-v][-x][-t]\n"; +} + +my %opts; +getopts('vxt', \%opts) || usage; +@ARGV == 0 or usage; + +my @spans = Dahdi::spans; + +sub show_xbus($) { + my $xbus = shift or die; + my @xpds = $xbus->xpds; + my $label = '[' . $xbus->label() . ']'; + my $connector = ($xbus->status eq 'CONNECTED') ? $xbus->connector : "MISSING"; + printf " LABEL=%-20s CONNECTOR=%-20s\n", $label, $connector; + foreach my $xpd (@xpds) { + my $reg = $xpd->dahdi_registration; + my $channels = '(' . $xpd->channels . ')'; + my $span; + my $spanstr; + if($reg && @spans) { + ($span) = grep { $_->name eq $xpd->fqn } @spans; + $spanstr = ($span) ? ("Span " . $span->num) : ""; + } else { + $spanstr = "Unregistered"; + } + my $master = ''; + #$master = "XPP-SYNC" if $xpd->is_sync_master; + $master .= " DAHDI-SYNC" if defined($span) && $span->is_dahdi_sync_master; + printf "\t%-10s: %-8s %-5s %s %s\n", $xpd->fqn, $xpd->type, $channels, $spanstr, $master; + } +} + +my %seen; +my $format = "%-20s %-12s %4s:%4s %s\n"; + +sub show_disconnected(%) { + my %seen = @_; + + my $notified_lost = 0; + foreach my $xbus (Dahdi::Xpp::xbuses) { + if(!$seen{$xbus->name}) { + print "----------- XPP Spans with disconnected hardware -----------\n" + unless $notified_lost++; + printf($format, $xbus->name, '', '', '', "NO HARDWARE"); + show_xbus($xbus) if $opts{'v'}; + } + } +} + +# FIXME: For verbose display we also need to see the XPP devices. +# If no spans are registered, this won't happen. A brute-force +# method for making it happen: +Dahdi::Xpp::xbuses if ($opts{'v'}); + +my @devices = Dahdi::Hardware->device_list; +foreach my $dev (@devices) { + my $driver = $dev->driver || ""; + my $xbus; + my $loaded; + my $tws_port; + my $tws_power; + my $tws_watchdog; + my $mppinfo; + if($dev->is_astribank) { + $xbus = $dev->xbus; + if($opts{'v'} || $opts{'t'}) { + Dahdi::Xpp::Mpp->mpp_addinfo($dev); + $mppinfo = $dev->mppinfo; + if(defined $mppinfo) { + $tws_port = $mppinfo->{TWINSTAR_PORT}; + $tws_power = $mppinfo->{TWINSTAR_POWER}; + $tws_watchdog = $mppinfo->{TWINSTAR_WATCHDOG}; + } + } + } + $loaded = $dev->loaded; + warn "driver should be '$driver' but is actually '$loaded'\n" + if defined($loaded) && $driver ne $loaded; + $driver = "$driver" . (($loaded) ? "+" : "-"); + if(defined $tws_power && defined $tws_watchdog) { + my $tws_active = $tws_watchdog && $tws_power->[0] && $tws_power->[1]; + $driver .= "[T]" if $tws_active; + } + my $description = $dev->description || ""; + printf $format, $dev->hardware_name, $driver, $dev->vendor, $dev->product, $description; + if($opts{'v'} && defined $mppinfo && exists $mppinfo->{MPP_TALK}) { + printf " MPP: TWINSTAR_PORT=$tws_port\n" if defined $tws_port; + printf " MPP: TWINSTAR_WATCHDOG=$tws_watchdog\n" if defined $tws_watchdog; + for(my $i = 0; $i < 2; $i++) { + printf " MPP: TWINSTAR_POWER[%d]=%d\n", + $i, $tws_power->[$i] if defined $tws_power; + } + } + if(!defined $xbus || !$xbus) { + next; + } + $seen{$xbus->name} = 1; + show_xbus($xbus) if $opts{'v'}; +} + +show_disconnected(%seen) if $opts{'x'}; + +__END__ + +=head1 NAME + +dahdi_hardware - Shows Dahdi hardware devices. + +=head1 SYNOPSIS + +dahdi_hardware [-v][-x] + +=head1 OPTIONS + +=over + +=item -v + +Verbose output - show spans used by each device etc. Currently only +implemented for the Xorcom Astribank. + +=item -x + +Show disconnected Astribank unit, if any. + +=back + +=head1 DESCRIPTION + +Show all Dahdi hardware devices. Devices are recognized according to +lists of PCI and USB IDs in Dahdi::Hardware::PCI.pm and +Dahdi::Hardware::USB.pm . For PCI it is possible to detect by +sub-vendor and sub-product ID as well. + +The first output column is the connector: a bus specific field that +shows where this device is. + +The second field shows which driver should handle the device. a "-" sign +marks that the device is not yet handled by this driver. A "+" sign +means that the device is handled by the driver. + +For the Xorcom Astribank (and in the future: for other Dahdi devices) +some further information is provided from the driver. Those extra lines +always begin with spaces. + +Example output: + +Without drivers loaded: + + usb:001/002 xpp_usb- e4e4:1152 Astribank-multi FPGA-firmware + usb:001/003 xpp_usb- e4e4:1152 Astribank-multi FPGA-firmware + pci:0000:01:0b.0 wctdm- e159:0001 Wildcard TDM400P REV H + +With drivers loaded, without -v: + usb:001/002 xpp_usb+ e4e4:1152 Astribank-multi FPGA-firmware + usb:001/003 xpp_usb+ e4e4:1152 Astribank-multi FPGA-firmware + pci:0000:01:0b.0 wctdm+ e159:0001 Wildcard TDM400P REV E/F + +With drivers loaded, with -v: + usb:001/002 xpp_usb+ e4e4:1152 Astribank-multi FPGA-firmware + LABEL=[usb:123] CONNECTOR=usb-0000:00:1d.7-1 + XBUS-00/XPD-00: FXS Span 2 + XBUS-00/XPD-10: FXS Span 3 + XBUS-00/XPD-20: FXS Span 4 + XBUS-00/XPD-30: FXS Span 5 + usb:001/003 xpp_usb+ e4e4:1152 Astribank-multi FPGA-firmware + LABEL=[usb:4567] CONNECTOR=usb-0000:00:1d.7-4 + XBUS-01/XPD-00: FXS Span 6 XPP-SYNC + XBUS-01/XPD-10: FXO Span 7 + XBUS-01/XPD-20: FXO Span 8 + XBUS-01/XPD-30: FXO Span 9 + pci:0000:01:0b.0 wctdm+ e159:0001 Wildcard TDM400P REV E/F + diff --git a/xpp/dahdi_registration b/xpp/dahdi_registration new file mode 100755 index 0000000..2772e00 --- /dev/null +++ b/xpp/dahdi_registration @@ -0,0 +1,248 @@ +#! /usr/bin/perl -w +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use File::Basename; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); } + +use Dahdi; +use Dahdi::Span; +use Dahdi::Xpp; +use Dahdi::Xpp::Xbus; +use Dahdi::Xpp::Xpd; +use Getopt::Std; + +sub usage { + die "Usage: $0 [-v] [-R] [-s sort_order] [on|off|1|0]\n"; +} + +sub check_param { + my $param = shift || die; + open(F, $param) || return ''; + my $val = ; + close F; + chomp $val; + return $val; +} + +my %opts; +getopts('vRs:', \%opts) || usage; + +my $dahdi_autoreg = check_param('/sys/module/xpp/parameters/dahdi_autoreg') eq 'Y'; +my $auto_assign_spans = check_param('/sys/module/dahdi/parameters/auto_assign_spans') ne '0'; +my $assigned_spans_config = $ENV{'ASSIGNED_SPANS_CONF_FILE'} || '/etc/dahdi/assigned-spans.conf'; +my $span_types_config = $ENV{'SPAN_TYPES_CONF_FILE'} || '/etc/dahdi/span-types.conf'; +my $have_assigned_spans_config = -f $assigned_spans_config || 0; +my $have_span_types_config = -f $span_types_config || 0; + +# Spans will be auto-assigned by default if either: +# - Driver $auto_assign_spans them or +# - Udev script see that we $have_span_types_config and it "add" them +my $default_auto_assign = $auto_assign_spans || $have_assigned_spans_config; + +my $sorter; +my $sort_order = $opts{'s'}; +if(defined $sort_order) { + my $sorter = Dahdi::Xpp::sorters($sort_order); + + if(!defined $sorter) { + my @sorter_names = Dahdi::Xpp::sorters; + print STDERR "Unknown sort order $sort_order. Select from:\n\t"; + print STDERR join("\n\t", @sorter_names); + print STDERR "\n"; + exit 1; + } +} + +@ARGV == 0 or @ARGV == 1 or usage; +my $on = shift; +my $verbose = $opts{'v'}; +my $should_output = 1; + +#print "dahdi_autoreg=$dahdi_autoreg auto_assign_spans=$auto_assign_spans have_assigned_spans_config='$have_assigned_spans_config' have_span_types_config='$have_span_types_config'\n"; + +if(defined($on)) { # Translate to booleans + $on = uc($on); + $on =~ /^(ON|OFF|1|0)$/ or usage; + $on = ($on eq 'ON') ? 1 : 0; + $should_output = 0 unless $verbose; +} + +sub state2str($) { + return (shift)?"on":"off"; +} + +sub myprintf { + printf @_ if $should_output; +} + +foreach my $xbus (Dahdi::Xpp::xbuses($sorter)) { + my $prev = $xbus->dahdi_registration($on); + if(!defined($prev)) { # Failure + printf STDERR "%s: Failed %s\n", $xbus->name, $!; + next; + } + my $reg_str; + if (defined $on) { + $reg_str = ($on) ? "registering" : "unregistering"; + } else { + $reg_str = ($prev) ? "registered" : "unregistered"; + } + myprintf "%-10s\t%3s-%s\t%s (%s)\n", + $xbus->name, $xbus->xpporder, $xbus->label, $xbus->connector, + $reg_str; + next unless $xbus->status eq 'CONNECTED'; + # Only assign if no default assignment, or forced by '-R' option + if (defined($on) && $on) { + if ($opts{'R'} || ! $default_auto_assign) { + # Emulate /etc/dahdi/assigned-spans.conf: + # - We iterate over $xbus according to /etc/dahdi/xpp_order + # - We "auto" assign all spans of current $xbus + my $devpath = sprintf "/sys/bus/dahdi_devices/devices/astribanks:xbus-%02d", $xbus->num; + my @cmd = ('dahdi_span_assignments', 'auto', $devpath); + system @cmd; + warn "Failed '@cmd' (status=$?)\n" if $?; + } + # wait for UDEV to do its stuff + system "dahdi_waitfor_span_assignments assigned"; + } + foreach my $xpd (Dahdi::Xpp::Xpd::telephony_devs($xbus->xpds())) { + my $spanno = $xpd->xpd_getattr('span'); + myprintf "\t%-10s: ", $xpd->fqn; + my $spanstr = ($spanno) ? ("Span " . $spanno) : "unassigned"; + myprintf "%s\n", $spanstr ; + } +} +myprintf "# Sorted: $sort_order\n" if defined $sort_order; + +__END__ + +=head1 NAME + +dahdi_registration - Handle registration of Xorcom XPD modules in dahdi. + +=head1 SYNOPSIS + +dahdi_registration [-v] [-s sortorder] [-R] [on|off] + +=head1 DESCRIPTION + +Without parameters, show all connected XPDs sorted by physical connector order. +Each one is show to be unregistered (off), or registered to a specific dahdi +span (the span number is shown). + +All registerations/deregisterations are sorted by physical connector string. + +Span registration should generally always succeed. Span unregistration may +fail if channels from the span are in use by e.g. asterisk. In such a case +you'll also see those channels as '(In use)' in the output of lsdahdi(8). + +dahdi_registration is intended to be used when the kernel module parameter +B is false (and implicitly: when the module parameter +B is true). See also the NOTES section regarding +C. + +If dahdi_autoreg is true, the program will normally do nothing. + +=head2 Parameters + +off -- deregisters all XPD's from dahdi. + +on -- registers all XPD's to dahdi. + +=head2 Options + +=over + +=item -v + +verbose output. + +=item -R + +Force operations (on/off) even if the module parameter B +for xpp is enabled (which makes this program unneeded). + +=item -s I + +The sort order to use. + +=back + +If the option is not used, the sort order is taken from the environment +variable XBUS_SORT and failing that: the hard-coded default of +SORT_XPPORDER. + +The available sorting orders are documented in Dahdi::Xpp manual. + + + +=head2 Sample Output + +An example of the output of dahdi_registration for some registered +Astribanks: + + $ dahdi_registration -s type + XBUS-01 usb:0000153 usb-0000:00:10.4-2 + XBUS-01/XPD-00: on Span 1 + XBUS-01/XPD-01: on Span 2 + XBUS-00 usb:0000157 usb-0000:00:10.4-4 + XBUS-00/XPD-00: on Span 3 + XBUS-00/XPD-01: on Span 4 + XBUS-00/XPD-02: on Span 5 + XBUS-00/XPD-03: on Span 6 + XBUS-00/XPD-04: on Span 7 + XBUS-00/XPD-05: on Span 8 + XBUS-00/XPD-06: on Span 9 + XBUS-00/XPD-07: on Span 10 + XBUS-02 usb-0000:00:10.4-1 + XBUS-02/XPD-00: on Span 11 + XBUS-02/XPD-10: on Span 12 + # Sorted: type + +=head1 FILES + +=over + +=item /proc/xpp/XBUS-nn/XPD-mm/dahdi_registration + +Reading from this file shows if if the if the specific XPD is +registered. Writing to it 0 or 1 registers / unregisters the device. + +This should allow you to register / unregister a specific XPD rather +than all of them. + +=back + +=head1 NOTES + +dahdi_registration is intended to be used when the kernel module +parameter B is false (and implicitly: when the module +parameter B is true), that is, Astribank devices +as detected by XPP (xbus / xpd) do not register automatically with the +DAHDI core. This tool is used to register tem in an explicit order. It +works well, but only if you can arange for all of the Astribanks of the +system to be available (and not already registered) at a specific point +in time. + +Newer versions of DAHDI added support for registering a span to a +specific span/channelss numbers specification. This allows registering +them out of order. To use this capability, the module parameter +B should be unset (set to 0) and thus spans of +detected DAHDI devices could be registered using C +(which may also be run automatically from a udev hook). + +In this case there is no point in delaying XPP device registration with +dahdi and the parameter B should be set. +dahdi_registration will simply become a no-op. + +=head1 SEE ALSO + +B(8), B(8). + diff --git a/xpp/echo_loader.c b/xpp/echo_loader.c new file mode 100644 index 0000000..ca92883 --- /dev/null +++ b/xpp/echo_loader.c @@ -0,0 +1,876 @@ +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "echo_loader.h" +#include "debug.h" +#include +#include "parse_span_specs.h" + +#define DBG_MASK 0x03 +#define TIMEOUT 1000 +#define ECHO_MAX_CHANS 128 +#define ECHO_RIN_STREAM 0 +#define ECHO_ROUT_STREAM 1 +#define ECHO_SIN_STREAM 2 +#define ECHO_SOUT_STREAM 3 + +#define ECHO_RIN_STREAM2 4 +#define ECHO_SIN_STREAM2 6 +#define ECHO_ROUT_STREAM2 5 +#define ECHO_SOUT_STREAM2 7 + +#define EC_VER_TEST 0xABCD +#define EC_VER_INVALID 0xFFFF +static float oct_fw_load_timeout = 2.0; + +struct echo_mod { + tPOCT6100_INSTANCE_API pApiInstance; + UINT32 ulEchoChanHndl[256]; + struct astribank_device *astribank; + int maxchans; +}; + +enum xpp_packet_types { + SPI_SND_XOP = 0x0F, + SPI_RCV_XOP = 0x10, + TST_SND_XOP = 0x35, + TST_RCV_XOP = 0x36, +}; + +struct xpp_packet_header { + struct { + uint16_t len; + uint8_t op; + uint8_t unit; + } PACKED header; + union { + struct { + uint8_t header; + uint8_t flags; + uint8_t addr_l; + uint8_t addr_h; + uint8_t data_l; + uint8_t data_h; + } PACKED spi_pack; + struct { + uint8_t tid; + uint8_t tsid; + } PACKED tst_pack; + } alt; +} PACKED; + +static struct usb_buffer { + char data[PACKET_SIZE]; + int max_len; + int curr; + /* statistics */ + int min_send; + int max_send; + int num_sends; + long total_bytes; + struct timeval start; + struct timeval end; +} usb_buffer; + + +static void usb_buffer_init(struct astribank_device *astribank, struct usb_buffer *ub) +{ + ub->max_len = xusb_packet_size(astribank->xusb); + ub->curr = 0; + ub->min_send = INT_MAX; + ub->max_send = 0; + ub->num_sends = 0; + ub->total_bytes = 0; + gettimeofday(&ub->start, NULL); +} + +static long usb_buffer_usec(struct usb_buffer *ub) +{ + struct timeval now; + + gettimeofday(&now, NULL); + return (now.tv_sec - ub->start.tv_sec) * 1000000 + + (now.tv_usec - ub->start.tv_usec); +} + +static void usb_buffer_showstatistics(struct astribank_device *astribank, struct usb_buffer *ub) +{ + long usec; + + usec = usb_buffer_usec(ub); + AB_INFO(astribank, "Octasic statistics: packet_size=[%d, %ld, %d] packets=%d, bytes=%ld msec=%ld usec/packet=%ld\n", + ub->min_send, + ub->total_bytes / ub->num_sends, + ub->max_send, + ub->num_sends, ub->total_bytes, + usec / 1000, usec / ub->num_sends); +} + +static int usb_buffer_flush(struct astribank_device *astribank, struct usb_buffer *ub) +{ + int ret; + long t; + long sec; + static int last_sec; + + if (ub->curr == 0) + return 0; + ret = xusb_send(astribank->xusb, ub->data, ub->curr, TIMEOUT); + if (ret < 0) { + AB_ERR(astribank, "xusb_send failed: %d\n", ret); + return ret; + } + DBG("%s: Written %d bytes\n", __func__, ret); + if (ret > ub->max_send) + ub->max_send = ret; + if (ret < ub->min_send) + ub->min_send = ret; + ub->total_bytes += ret; + ub->num_sends++; + ub->curr = 0; + + sec = usb_buffer_usec(ub) / (1000 * 1000); + if (sec > last_sec) { + DBG("bytes/sec=%ld average len=%ld\n", + ub->total_bytes / sec, + ub->total_bytes / ub->num_sends); + last_sec = sec; + } + + /* + * Best result with high frequency firmware: 21 seconds + * Octasic statistics: packet_size=[10, 239, 510] packets=26806, bytes=6419640 usec=21127883 usec/packet=788 + * t = 0.3 * ret - 150; + */ + t = oct_fw_load_timeout * ret - 150; + if (t > 0) + usleep(t); + return ret; +} + +static int usb_buffer_append(struct astribank_device *astribank, struct usb_buffer *ub, + char *buf, int len) +{ + if (ub->curr + len >= ub->max_len) { + AB_ERR(astribank, "%s: buffer too small ub->curr=%d, len=%d, ub->max_len=%d\n", + __func__, ub->curr, len, ub->max_len); + return -ENOMEM; + } + memcpy(ub->data + ub->curr, buf, len); + ub->curr += len; + return len; +} + +static int usb_buffer_send(struct astribank_device *astribank, struct usb_buffer *ub, + char *buf, int len, int timeout, int recv_answer) +{ + int ret = 0; + + if (ub->curr + len >= ub->max_len) { + ret = usb_buffer_flush(astribank, ub); + if (ret < 0) + return ret; + } + + if ((ret = usb_buffer_append(astribank, ub, buf, len)) < 0) { + return ret; + } + DBG("%s: %d bytes %s\n", __func__, len, (recv_answer) ? "recv" : "send"); + if (recv_answer) { + struct xpp_packet_header *phead; + + ret = usb_buffer_flush(astribank, ub); + if (ret < 0) + return ret; + ret = xusb_recv(astribank->xusb, buf, PACKET_SIZE, TIMEOUT); + if (ret <= 0) { + AB_ERR(astribank, "No USB packs to read: %s\n", strerror(-ret)); + return -EINVAL; + } + DBG("%s: %d bytes recv\n", __func__, ret); + phead = (struct xpp_packet_header *)buf; + if (phead->header.op != SPI_RCV_XOP && + phead->header.op != TST_RCV_XOP) { + AB_ERR(astribank, "Got unexpected reply OP=0x%02X\n", + phead->header.op); + dump_packet(LOG_ERR, DBG_MASK, "hexline[ERR]", + buf, ret); + return -EINVAL; + } + dump_packet(LOG_DEBUG, DBG_MASK, "dump:echoline[R]", (char *)phead, phead->header.len); + switch(phead->header.op) { + case SPI_RCV_XOP: + ret = (phead->alt.spi_pack.data_h << 8) | phead->alt.spi_pack.data_l; + break; + case TST_RCV_XOP: + ret = (phead->alt.tst_pack.tid << 8) | phead->alt.tst_pack.tsid; + break; + default: + ret = -EINVAL; + } + } + return ret; +} + +int spi_send(struct astribank_device *astribank, uint16_t addr, uint16_t data, int recv_answer, int ver) +{ + int ret; + char buf[PACKET_SIZE]; + struct xpp_packet_header *phead = (struct xpp_packet_header *)buf; + int pack_len; + int spi_flags; + + assert(astribank != NULL); + spi_flags = 0x30 | (recv_answer ? 0x40 : 0x00) | (ver ? 0x01 : 0x00); + pack_len = sizeof(phead->header) + sizeof(phead->alt.spi_pack); + phead->header.len = pack_len; + phead->header.op = SPI_SND_XOP; + phead->header.unit = 0x40; /* EC has always this unit num */ + phead->alt.spi_pack.header = 0x05; + phead->alt.spi_pack.flags = spi_flags; + phead->alt.spi_pack.addr_l = (addr >> 0) & 0xFF; + phead->alt.spi_pack.addr_h = (addr >> 8) & 0xFF; + phead->alt.spi_pack.data_l = (data >> 0) & 0xFF; + phead->alt.spi_pack.data_h = (data >> 8) & 0xFF; + + dump_packet(LOG_DEBUG, DBG_MASK, "dump:echoline[W]", (char *)phead, pack_len); + + + ret = usb_buffer_send(astribank, &usb_buffer, buf, pack_len, TIMEOUT, recv_answer); + if (ret < 0) { + AB_ERR(astribank, "usb_buffer_send failed: %d\n", ret); + return ret; + } + DBG("%s: Written %d bytes\n", __func__, ret); + return ret; +} + +int test_send(struct astribank_device *astribank) +{ + int ret; + char buf[PACKET_SIZE]; + struct xpp_packet_header *phead = (struct xpp_packet_header *)buf; + int pack_len; + + assert(astribank != NULL); + pack_len = sizeof(phead->header) + sizeof(phead->alt.tst_pack); + phead->header.len = 6; + phead->header.op = 0x35; + phead->header.unit = 0x00; + phead->alt.tst_pack.tid = 0x28; /* EC TestId */ + phead->alt.tst_pack.tsid = 0x00; /* EC SubId */ + + dump_packet(LOG_DEBUG, DBG_MASK, "dump:echoline[W]", + (char *)phead, pack_len); + + ret = usb_buffer_send(astribank, + &usb_buffer, buf, pack_len, TIMEOUT, 1); + if (ret < 0) { + AB_ERR(astribank, "usb_buffer_send failed: %d\n", ret); + return ret; + } + DBG("%s: Written %d bytes\n", __func__, ret); + return ret; +} + +int echo_send_data(struct astribank_device *astribank, const unsigned int addr, const unsigned int data) +{ + int ret; +/* DBG("SEND: %04X -> [%04X]\n", data, addr); + DBG("\t\t[%04X] <- %04X\n", 0x0008, (addr >> 20)); + DBG("\t\t[%04X] <- %04X\n", 0x000A, (addr >> 4) & ((1 << 16) - 1)); + DBG("\t\t[%04X] <- %04X\n", 0x0004, data); + DBG("\t\t[%04X] <- %04X\n", 0x0000, (((addr >> 1) & 0x7) << 9) | (1 << 8) | (3 << 12) | 1); + */ + + DBG("SND:\n"); + ret = spi_send(astribank, 0x0008, (addr >> 20) , 0, 0); + if (ret < 0) + goto failed; + ret = spi_send(astribank, 0x000A, (addr >> 4) & ((1 << 16) - 1) , 0, 0); + if (ret < 0) + goto failed; + ret = spi_send(astribank, 0x0004, data , 0, 0); + if (ret < 0) + goto failed; + ret = spi_send(astribank, 0x0000, (((addr >> 1) & 0x7) << 9) | + (1 << 8) | (3 << 12) | 1 , 0, 0); + if (ret < 0) + goto failed; + return cOCT6100_ERR_OK; +failed: + AB_ERR(astribank, "echo_send_data: spi_send failed (ret = %d)\n", ret); + return ret; +} + +int echo_recv_data(struct astribank_device *astribank, const unsigned int addr) +{ + unsigned int data = 0x00; + int ret; + + DBG("RCV:\n"); + ret = spi_send(astribank, 0x0008, (addr >> 20) , 0, 0); + if (ret < 0) + goto failed; + ret = spi_send(astribank, 0x000A, (addr >> 4) & ((1 << 16) - 1) , 0, 0); + if (ret < 0) + goto failed; + ret = spi_send(astribank, 0x0000, (((addr >> 1) & 0x7) << 9) | + (1 << 8) | 1 , 0, 0); + if (ret < 0) + goto failed; + ret = spi_send(astribank, 0x0004, data , 1, 0); + if (ret < 0) + goto failed; + return ret; +failed: + AB_ERR(astribank, "echo_recv_data: spi_send failed (ret = %d)\n", ret); + return ret; +} + +int load_file(char *filename, unsigned char **ppBuf, UINT32 *pLen) +{ + unsigned char *pbyFileData = NULL; + FILE *pFile; + + DBG("Loading %s file...\n", filename); + pFile = fopen(filename, "rb"); + if (pFile == NULL) { + ERR("fopen: %s\n", strerror(errno)); + return -ENODEV; + } + + fseek(pFile, 0L, SEEK_END); + *pLen = ftell(pFile); + fseek(pFile, 0L, SEEK_SET); + + pbyFileData = (unsigned char *)malloc(*pLen); + if (pbyFileData == NULL) { + fclose(pFile); + ERR("malloc\n"); + return -ENODEV; + } else { + DBG("allocated mem for pbyFileData\n"); + } + if (fread(pbyFileData, 1, *pLen, pFile) != *pLen) { + fclose(pFile); + ERR("fread: %s\n", strerror(errno)); + return -ENODEV; + } + fclose(pFile); + DBG("Successful loading %s file into memory " + "(size = %d, DUMP: first = %02X %02X, last = %02X %02X)\n", + filename, *pLen, + pbyFileData[0], pbyFileData[1], + pbyFileData[(*pLen)-2], pbyFileData[(*pLen)-1]); + *ppBuf = pbyFileData; + return 0; +} + +UINT32 Oct6100UserGetTime(tPOCT6100_GET_TIME f_pTime) +{ + ///* Why couldn't they just take a timeval like everyone else? */ + struct timeval tv; + unsigned long long total_usecs; + unsigned int mask = ~0; + + gettimeofday(&tv, 0); + total_usecs = (((unsigned long long)(tv.tv_sec)) * 1000000) + + (((unsigned long long)(tv.tv_usec))); + f_pTime->aulWallTimeUs[0] = (total_usecs & mask); + f_pTime->aulWallTimeUs[1] = (total_usecs >> 32); + //printf("Inside of Oct6100UserGetTime\n"); + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserMemSet(PVOID f_pAddress, UINT32 f_ulPattern, UINT32 f_ulLength) +{ + memset(f_pAddress, f_ulPattern, f_ulLength); + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserMemCopy(PVOID f_pDestination, const void *f_pSource, UINT32 f_ulLength) +{ + memcpy(f_pDestination, f_pSource, f_ulLength); + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserCreateSerializeObject(tPOCT6100_CREATE_SERIALIZE_OBJECT f_pCreate) +{ + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserDestroySerializeObject(tPOCT6100_DESTROY_SERIALIZE_OBJECT f_pDestroy) +{ +#ifdef OCTASIC_DEBUG + ERR("I should never be called! (destroy serialize object)\n"); +#endif + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserSeizeSerializeObject(tPOCT6100_SEIZE_SERIALIZE_OBJECT f_pSeize) +{ + /* Not needed */ + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserReleaseSerializeObject(tPOCT6100_RELEASE_SERIALIZE_OBJECT f_pRelease) +{ + /* Not needed */ + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserDriverWriteApi(tPOCT6100_WRITE_PARAMS f_pWriteParams) +{ + const unsigned int addr = f_pWriteParams->ulWriteAddress; + const unsigned int data = f_pWriteParams->usWriteData; + const struct echo_mod *echo_mod = (struct echo_mod *)(f_pWriteParams->pProcessContext); + struct astribank_device *astribank = echo_mod->astribank; + int ret; + + ret = echo_send_data(astribank, addr, data); + if (ret < 0) { + ERR("echo_send_data failed (ret = %d)\n", ret); + return cOCT6100_ERR_FATAL_DRIVER_WRITE_API; + } + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserDriverWriteSmearApi(tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams) +{ + unsigned int addr; + unsigned int data; + unsigned int len; + const struct echo_mod *echo_mod; + struct astribank_device *astribank; + unsigned int i; + + len = f_pSmearParams->ulWriteLength; + echo_mod = (struct echo_mod *)f_pSmearParams->pProcessContext; + astribank = echo_mod->astribank; + for (i = 0; i < len; i++) { + int ret; + + addr = f_pSmearParams->ulWriteAddress + (i << 1); + data = f_pSmearParams->usWriteData; + ret = echo_send_data(astribank, addr, data); + if (ret < 0) { + ERR("echo_send_data failed (ret = %d)\n", ret); + return cOCT6100_ERR_FATAL_DRIVER_WRITE_API; + } + } + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserDriverWriteBurstApi(tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams) +{ + unsigned int addr; + unsigned int data; + unsigned int len = f_pBurstParams->ulWriteLength; + const struct echo_mod *echo_mod = (struct echo_mod *)f_pBurstParams->pProcessContext; + struct astribank_device *astribank = echo_mod->astribank; + unsigned int i; + + for (i = 0; i < len; i++) { + int ret; + + addr = f_pBurstParams->ulWriteAddress + (i << 1); + data = f_pBurstParams->pusWriteData[i]; + ret = echo_send_data(astribank, addr, data); + if (ret < 0) { + ERR("echo_send_data failed (ret = %d)\n", ret); + return cOCT6100_ERR_FATAL_DRIVER_WRITE_API; + } + } + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserDriverReadApi(tPOCT6100_READ_PARAMS f_pReadParams) +{ + const unsigned int addr = f_pReadParams->ulReadAddress; + const struct echo_mod *echo_mod; + struct astribank_device *astribank; + int ret; + + echo_mod = (struct echo_mod *)f_pReadParams->pProcessContext; + astribank = echo_mod->astribank; + ret = echo_recv_data(astribank, addr); + if (ret < 0) { + ERR("echo_recv_data failed (%d)\n", ret); + return cOCT6100_ERR_FATAL_DRIVER_READ_API; + } + *f_pReadParams->pusReadData = ret; + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams) +{ + unsigned int addr; + unsigned int len; + const struct echo_mod *echo_mod; + struct astribank_device *astribank; + unsigned int i; + + len = f_pBurstParams->ulReadLength; + echo_mod = (struct echo_mod *)f_pBurstParams->pProcessContext; + astribank = echo_mod->astribank; + for (i = 0;i < len; i++) { + unsigned int ret; + + addr = f_pBurstParams->ulReadAddress + (i << 1); + ret = echo_recv_data(astribank, addr); + if (ret < 0) { + ERR("echo_recv_data failed (%d)\n", ret); + return cOCT6100_ERR_FATAL_DRIVER_READ_API; + } + f_pBurstParams->pusReadData[i] = ret; + } + return cOCT6100_ERR_OK; +} + +inline int get_ver(struct astribank_device *astribank) +{ + return spi_send(astribank, 0, 0, 1, 1); +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +UINT32 init_octasic(char *filename, struct astribank_device *astribank, struct span_specs *span_specs) +{ + int cpld_ver; + struct echo_mod *echo_mod; + UINT32 nChan; + UINT32 nSlot; + UINT32 pcmLaw; + UINT32 ulResult; + + tOCT6100_GET_INSTANCE_SIZE InstanceSize; + tPOCT6100_INSTANCE_API pApiInstance; + tOCT6100_CHIP_OPEN OpenChip; + + UINT32 ulImageByteSize; + PUINT8 pbyImageData = NULL; + + /*=========================================================================*/ + /* Channel resources.*/ + tOCT6100_CHANNEL_OPEN ChannelOpen; + UINT32 ulChanHndl; + enum tdm_codec tdm_codec; + int spanno; + + if (test_send(astribank) < 0) + return cOCT6100_ERR_FATAL; + cpld_ver = get_ver(astribank); + AB_INFO(astribank, "Check EC_CPLD version: %d\n", cpld_ver); + if (cpld_ver < 0) + return cOCT6100_ERR_FATAL; + else if (cpld_ver == EC_VER_TEST) { + AB_INFO(astribank, "+---------------------------------------------------------+\n"); + AB_INFO(astribank, "| WARNING: TEST HARDWARE IS ON THE BOARD INSTEAD OF EC!!! |\n"); + AB_INFO(astribank, "+---------------------------------------------------------+\n"); + return cOCT6100_ERR_OK; + } + + + /**************************************************************************/ + /**************************************************************************/ + /* 1) Configure and Open the OCT6100. */ + /**************************************************************************/ + /**************************************************************************/ + + memset(&InstanceSize, 0, sizeof(tOCT6100_GET_INSTANCE_SIZE)); + memset(&OpenChip, 0, sizeof(tOCT6100_CHIP_OPEN)); + + echo_mod = malloc(sizeof(struct echo_mod)); + if (!echo_mod) { + AB_ERR(astribank, "cannot allocate memory for echo_mod\n"); + return cOCT6100_ERR_FATAL; + } + DBG("allocated mem for echo_mod\n"); + + memset(echo_mod, 0, sizeof(struct echo_mod)); + + /* Fill the OCT6100 Chip Open configuration structure with default values */ + + ulResult = Oct6100ChipOpenDef(&OpenChip); + if (ulResult != cOCT6100_ERR_OK) { + AB_ERR(astribank, "Oct6100ChipOpenDef failed: result=%X\n", + ulResult); + return ulResult; + } + + OpenChip.pProcessContext = echo_mod; + /* Configure clocks */ + + /* upclk oscillator is at 33.33 Mhz */ + OpenChip.ulUpclkFreq = cOCT6100_UPCLK_FREQ_33_33_MHZ; + + /* mclk will be generated by internal PLL at 133 Mhz */ + OpenChip.fEnableMemClkOut = TRUE; + OpenChip.ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ; + + /* General parameters */ + OpenChip.fEnableChannelRecording = TRUE; + + /* Chip ID.*/ + OpenChip.ulUserChipId = 1; + + /* Set the max number of accesses to 1024 to speed things up */ + /* OpenChip.ulMaxRwAccesses = 1024; */ + + /* Set the maximums that the chip needs to support for this test */ + OpenChip.ulMaxChannels = 256; + OpenChip.ulMaxPlayoutBuffers = 2; + + OpenChip.ulMaxBiDirChannels = 0; + OpenChip.ulMaxConfBridges = 0; + OpenChip.ulMaxPhasingTssts = 0; + OpenChip.ulMaxTdmStreams = 8; + OpenChip.ulMaxTsiCncts = 0; + + /* External Memory Settings: Use DDR memory*/ + OpenChip.ulMemoryType = cOCT6100_MEM_TYPE_DDR; + + OpenChip.ulNumMemoryChips = 1; + OpenChip.ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_32MB; + + + /* Load the image file */ + ulResult = load_file( filename, + &pbyImageData, + &ulImageByteSize); + + if (ulResult != 0) { + AB_ERR(astribank, "Failed load_file %s (%08X)\n", filename, ulResult); + return ulResult; + } + if (pbyImageData == NULL || ulImageByteSize == 0){ + AB_ERR(astribank, "Bad pbyImageData or ulImageByteSize\n"); + return cOCT6100_ERR_FATAL; + } + + /* Assign the image file.*/ + OpenChip.pbyImageFile = pbyImageData; + OpenChip.ulImageSize = ulImageByteSize; + + /* + * Inserting default values into tOCT6100_GET_INSTANCE_SIZE + * structure parameters. + */ + Oct6100GetInstanceSizeDef(&InstanceSize); + + /* Get the size of the OCT6100 instance structure. */ + ulResult = Oct6100GetInstanceSize(&OpenChip, &InstanceSize); + if (ulResult != cOCT6100_ERR_OK) { + AB_ERR(astribank, "Oct6100GetInstanceSize failed (%08X)\n", + ulResult); + return ulResult; + } + + pApiInstance = malloc(InstanceSize.ulApiInstanceSize); + echo_mod->pApiInstance = pApiInstance; + echo_mod->astribank = astribank; + + if (!pApiInstance) { + AB_ERR(astribank, "Out of memory (can't allocate %d bytes)!\n", + InstanceSize.ulApiInstanceSize); + return cOCT6100_ERR_FATAL; + } + + /* Perform actual open of chip */ + ulResult = Oct6100ChipOpen(pApiInstance, &OpenChip); + if (ulResult != cOCT6100_ERR_OK) { + AB_ERR(astribank, "Oct6100ChipOpen failed: result=%X\n", + ulResult); + return ulResult; + } + DBG("%s: OCT6100 is open\n", __func__); + + /* Free the image file data */ + free(pbyImageData); + + /**************************************************************************/ + /**************************************************************************/ + /* 2) Open channels in echo cancellation mode. */ + /**************************************************************************/ + /**************************************************************************/ + + for (nChan = 0; nChan < ECHO_MAX_CHANS; nChan++) { + nSlot = nChan; + /* open a channel.*/ + Oct6100ChannelOpenDef(&ChannelOpen); + + /* Assign the handle memory.*/ + ChannelOpen.pulChannelHndl = &ulChanHndl; + + /* Set the channel to work at the echo cancellation mode.*/ + ChannelOpen.ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_NORMAL; + + spanno = nChan % 4; + assert(spanno >= 0 && spanno < MAX_SPANNO); + tdm_codec = span_specs->span_is_alaw[spanno]; + if (tdm_codec == TDM_CODEC_UNKNOWN) { + AB_ERR(astribank, "Calculated bad alaw/ulaw on channel %d\n", nChan); + return cOCT6100_ERR_FATAL; + } + if (nChan < 4) + AB_INFO(astribank, "ECHO PRI port %d = %s\n", spanno+1, (tdm_codec == TDM_CODEC_ALAW) ? "alaw" : "ulaw"); + + pcmLaw = ((tdm_codec == TDM_CODEC_ALAW) ? cOCT6100_PCM_A_LAW: cOCT6100_PCM_U_LAW); + + /* Configure the TDM interface.*/ + ChannelOpen.TdmConfig.ulRinPcmLaw = pcmLaw; + ChannelOpen.TdmConfig.ulRinStream = ECHO_RIN_STREAM; + ChannelOpen.TdmConfig.ulRinTimeslot = nSlot; + + ChannelOpen.TdmConfig.ulSinPcmLaw = pcmLaw; + ChannelOpen.TdmConfig.ulSinStream = ECHO_SIN_STREAM; + ChannelOpen.TdmConfig.ulSinTimeslot = nSlot; + + ChannelOpen.TdmConfig.ulRoutPcmLaw = pcmLaw; + ChannelOpen.TdmConfig.ulRoutStream = ECHO_ROUT_STREAM; + ChannelOpen.TdmConfig.ulRoutTimeslot = nSlot; + + ChannelOpen.TdmConfig.ulSoutPcmLaw = pcmLaw; + ChannelOpen.TdmConfig.ulSoutStream = ECHO_SOUT_STREAM; + ChannelOpen.TdmConfig.ulSoutTimeslot = nSlot; + + /* Set the desired VQE features.*/ + ChannelOpen.VqeConfig.fEnableNlp = TRUE; + ChannelOpen.VqeConfig.fRinDcOffsetRemoval = TRUE; + ChannelOpen.VqeConfig.fSinDcOffsetRemoval = TRUE; + + ChannelOpen.VqeConfig.ulComfortNoiseMode = cOCT6100_COMFORT_NOISE_NORMAL; + /* cOCT6100_COMFORT_NOISE_NORMAL + cOCT6100_COMFORT_NOISE_EXTENDED, + cOCT6100_COMFORT_NOISE_OFF, + cOCT6100_COMFORT_NOISE_FAST_LATCH + */ + ulResult = Oct6100ChannelOpen( pApiInstance, + &ChannelOpen); + if (ulResult != cOCT6100_ERR_OK) { + AB_ERR(astribank, "Found error on chan %d\n", nChan); + return ulResult; + } + } + + /**************************************************************************/ + /**************************************************************************/ + /* *) Open channels in echo cancellation mode for second bus. */ + /**************************************************************************/ + /**************************************************************************/ + + for (nChan = 8; nChan < 32; nChan++) { + nSlot = (nChan >> 3) * 32 + (nChan & 0x07); + /* open a channel.*/ + Oct6100ChannelOpenDef(&ChannelOpen); + + /* Assign the handle memory.*/ + ChannelOpen.pulChannelHndl = &ulChanHndl; + + /* Set the channel to work at the echo cancellation mode.*/ + ChannelOpen.ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_NORMAL; + + /* Configure the TDM interface.*/ + ChannelOpen.TdmConfig.ulRinStream = ECHO_RIN_STREAM2;; + ChannelOpen.TdmConfig.ulRinTimeslot = nSlot; + + ChannelOpen.TdmConfig.ulSinStream = ECHO_SIN_STREAM2; + ChannelOpen.TdmConfig.ulSinTimeslot = nSlot; + + ChannelOpen.TdmConfig.ulRoutStream = ECHO_ROUT_STREAM2; + ChannelOpen.TdmConfig.ulRoutTimeslot = nSlot; + + ChannelOpen.TdmConfig.ulSoutStream = ECHO_SOUT_STREAM2; + ChannelOpen.TdmConfig.ulSoutTimeslot = nSlot; + + /* Set the desired VQE features.*/ + ChannelOpen.VqeConfig.fEnableNlp = TRUE; + ChannelOpen.VqeConfig.fRinDcOffsetRemoval = TRUE; + ChannelOpen.VqeConfig.fSinDcOffsetRemoval = TRUE; + + ChannelOpen.VqeConfig.ulComfortNoiseMode = cOCT6100_COMFORT_NOISE_NORMAL; + /* cOCT6100_COMFORT_NOISE_NORMAL + cOCT6100_COMFORT_NOISE_EXTENDED, + cOCT6100_COMFORT_NOISE_OFF, + cOCT6100_COMFORT_NOISE_FAST_LATCH + */ + ulResult = Oct6100ChannelOpen( pApiInstance, + &ChannelOpen); + if (ulResult != cOCT6100_ERR_OK) { + AB_ERR(astribank, "Found error on chan %d\n", nChan); + return ulResult; + } + } + + + DBG("%s: Finishing\n", __func__); + free(pApiInstance); + free(echo_mod); + return cOCT6100_ERR_OK; + +} +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +int load_echo(struct astribank_device *astribank, char *filename, int default_is_alaw, const char *span_spec) +{ + int ret; + UINT32 octasic_status; + struct span_specs *span_specs; + + span_specs = parse_span_specifications(span_spec, default_is_alaw); + if (!span_specs) { + AB_ERR(astribank, "ECHO parsing span specs failed\n"); + return -EFAULT; + } + AB_INFO(astribank, "Loading ECHOCAN Firmware: %s (default %s)\n", + filename, (default_is_alaw) ? "alaw" : "ulaw"); + usb_buffer_init(astribank, &usb_buffer); + octasic_status = init_octasic(filename, astribank, span_specs); + free_span_specifications(span_specs); + if (octasic_status != cOCT6100_ERR_OK) { + AB_ERR(astribank, "ECHO %s burning failed (%08X)\n", + filename, octasic_status); + return -ENODEV; + } + ret = usb_buffer_flush(astribank, &usb_buffer); + if (ret < 0) { + AB_ERR(astribank, "ECHO %s buffer flush failed (%d)\n", filename, ret); + return -ENODEV; + } + usb_buffer_showstatistics(astribank, &usb_buffer); + return 0; +} + +int echo_ver(struct astribank_device *astribank) +{ + usb_buffer_init(astribank, &usb_buffer); + return get_ver(astribank); +} + diff --git a/xpp/echo_loader.h b/xpp/echo_loader.h new file mode 100644 index 0000000..2bffda2 --- /dev/null +++ b/xpp/echo_loader.h @@ -0,0 +1,32 @@ +#ifndef ECHO_LOADER_H +#define ECHO_LOADER_H +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include "astribank_usb.h" + +int spi_send(struct astribank_device *astribank, uint16_t addr, uint16_t data, int recv_answer, int ver); +int load_echo(struct astribank_device *astribank, char *filename, int is_alaw, const char *span_spec); +int echo_ver(struct astribank_device *astribank); + +#endif /* ECHO_LOADER_H */ diff --git a/xpp/genconf_parameters b/xpp/genconf_parameters new file mode 100644 index 0000000..c27f960 --- /dev/null +++ b/xpp/genconf_parameters @@ -0,0 +1,169 @@ +# +# /etc/dahdi/genconf_parameters +# +# This file contains parameters that affect the +# dahdi_genconf configuration generator. +# +# Syntax: +# * A comment from '#' to end of line +# * Blank lines ignored +# * Whitespace at end of line trimmed +# * Single valued items: +# key value +# * List valued items: +# key +# value1 +# value2 +# ... +# + +# When generating extensions for chan_dahdi.conf or users.conf etc: the +# extension number will be channel_number+base_exten . The default is: +#base_exten 4000 +# +# Make FXS (analog phones) extensions answer immediately (sets +# 'immediate = yes' for them in chan_dahdi.conf). Don't enable this before +# you're read documentation about this option. +#fxs_immediate yes +# +# For FXS (analog phones) - use KS or LS? ks is the only method for +# Asterisk to provide disconnect supervision and thus it would normally +# be preferred and is the default. +#fxs_default_start ls +# +# For FXO (analog lines) - use KS or LS? KS is the default and is +# normally the better choice as it allows detecting hang-ups on many +# lines. +#fxo_default_start ls + +# Set tone zone values. This is used for playing tones (busy, dial-tone +# and such). The default is 'us'. This sets the value for both loadzone +# and defaultzone in system.conf . +#lc_country il + +# The dialplan context into which to send trunks in chan_dahdi.conf or +# users.conf. The default value is: +#context_lines from-pstn +# +# The dialplan context into which to send extensions in chan_dahdi.conf or +# users.conf. The default value is: +#context_phones from-internal +# +# Two extra contexts for the input ports and output ports of an +# Astribank. Default values are: +#context_input astbank-input +#context_output astbank-output + +# A group to put all analog phones in. By default 0, so you can dial to +# the 'first phone available' using Dahdi/g5 . +#group_phones 5 +# +# A group in which to put all the channels belonging to some trunk. +# Thus you can dial through "some trunk" using Dahdi/G0/NUMBER +#group_lines 0 + +# Channels of digital trunk of span N are also added to group 10+N (that +# is: 14 for channels of span 4). + +# Do we want to use PtP ('bri') or PtMP ('bri_ptmp') for BRI? PtMP +# allows connecting several CPE devices on the same network device +# (several BRI phones on the same line, kind of like several analog +# phones on the same analog line). However it is generally brings +# unnecessary complexity for a pbx-pbx connection. It is still the +# default as this is normally what you get for a BRI PSTN connection. +#bri_sig_style bri +# +# If this option is set (that is: not remmed-out), BRI NT ports will +# also be set as overlap. This is useful if you want to connect ISDN +# phones. +#brint_overlap + +# The echo canceler to use. If you have a hardware echo canceler, just +# leave it be, as this one won't be used anyway. +# +# The default is mg2, but it may change in the future. E.g: a packager +# that bundles a better echo canceler may set it as the default, or +# dahdi_genconf will scan for the "best" echo canceler. +# +#echo_can hpec +#echo_can oslec +#echo_can none # to avoid echo canceler altogether + +# bri_hardhdlc: +# 'yes' - forces BRI cards to use 'hardhdlc' signalling. +# 'no' - forces BRI cards to use 'dchan' (an alias for 'fcshdlc'). +# It is usefull only for dahdi with the bristuff patch. +# +# If it is left out or set to 'auto': +# * Information supplied by the driver is used to decide: +# - Currently implemented for Astribanks. +# - Taken from /sys/bus/xpds/drivers/bri/dchan_hardhdlc. +# * Without this info, falls back to 'hardhdlc'. +#bri_hardhdlc auto + +# For MFC/R2 Support: 'R2' will make E1 spans CAS and with the +# 'r2_idle_bits' bit in system.conf . It will also make dahdi_genconf default +# to generating the channels of this card in unicall.conf rather than in +# chan_dahdi.conf . The meaning of this may be extended somehow to support +# R2 through openr2/chan_dahdi later on. +#pri_connection_type R2 +#pri_connection_type CAS +# +# Explicitly set the idle bits for E1 CAS (Sample value is the default): +#r2_idle_bits 1101 +# +# Set T1 framing type to d4 instead of esf: +#tdm_framing d4 +# +# Use E&M on CAS (default is FXS/FXO). If set, E1 spans will be used as +# E&M-E1 and T1 will use the requested type: +#em_signalling em +#em_signalling em_w +#em_signalling featd +#em_signalling featdtmf +#em_signalling featdtmf_ta +#em_signalling featb +#em_signalling fgccama +#em_signalling fgccamamf +# +# pri_termtype contains a list of settings: +# Currently the only setting is for TE or NT (the default is TE). This +# sets two different but normally related configuration items: +# +# A TE span will have *_cpe signalling in Asterisk and will also get +# timing from the remote party. +# +# A NT span will have *_new signalling in Asterisk and will provide +# timing to the remote party. +# +# pri_termtype is a list if span specs and configuration (TE/NT) for +# them. The first spec that matches is used. The matching is of perl +# regular expressions, but with '*' and '?' have their meaning from +# basic regular expressions. +#pri_termtype +# SPAN/2 NT +# SPAN/4 NT +# +#pri_termtype +# SPAN/* NT +# +# Astribanks can be matched by span and also by their: +# LABEL + XPD number: +# this is burned into the Astribank and won't change +# if it's connected via different USB port/hub +# CONNECTOR + XPD number: +# The USB path to which the Astribank is connected. +# Replacing an Astribank and connecting to the same USB port/hub +# would not change this property. However, any change in USB +# wiring (e.g: adding another hub) may alter this. +# NUM (XBUS number) + XPD number: +# The XBUS number. This is not stable and may even change +# between boots. +# +#pri_termtype +# LABEL/usb:INT01216/XPD-0[123] NT +# LABEL/usb:INT00375/XPD-0[123] NT +# CONNECTOR/@usb-0000:00:1d.7-1/XPD-0[123] NT +# CONNECTOR/@usb-0000:00:1d.7-2/XPD-0[123] NT +# NUM/XBUS-01/XPD-0[123] NT +# NUM/XBUS-03/XPD-0[123] NT diff --git a/xpp/hexfile.c b/xpp/hexfile.c new file mode 100644 index 0000000..1227b26 --- /dev/null +++ b/xpp/hexfile.c @@ -0,0 +1,568 @@ +/* + * Written by Oron Peled + * Copyright (C) 2006, 2007, 2008, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include "hexfile.h" + +static const char rcsid[] = "$Id$"; + +static parse_hexfile_report_func_t report_func = NULL; + +parse_hexfile_report_func_t parse_hexfile_set_reporting(parse_hexfile_report_func_t rf) +{ + parse_hexfile_report_func_t old_rf = report_func; + report_func = rf; + return old_rf; +} + +static void chomp(char buf[]) +{ + size_t last = strlen(buf) - 1; + while(last >= 0 && isspace(buf[last])) + buf[last--] = '\0'; +} + +static int hexline_checksum(struct hexline *hexline) +{ + unsigned int i; + unsigned int chksm = 0; + int ll = hexline->d.content.header.ll; + + for(i = 0; i <= sizeof(hexline->d.content.header) + ll; i++) { + chksm += hexline->d.raw[i]; + } + return chksm & 0xFF; +} + +int dump_hexline(int recordno, struct hexline *line, FILE *fp) +{ + uint8_t ll; + uint16_t offset; + uint8_t tt; + uint8_t old_chksum; + uint8_t new_chksum; + uint8_t *data; + unsigned int i; + + ll = line->d.content.header.ll; + offset = line->d.content.header.offset; + tt = line->d.content.header.tt; + fprintf(fp, ":%02X%04X%02X", ll, offset, tt); + data = line->d.content.tt_data.data; + for(i = 0; i < ll; i++) { + fprintf(fp, "%02X", data[i]); + } + old_chksum = data[ll]; + data[ll] = 0; + new_chksum = 0xFF - hexline_checksum(line) + 1; + data[ll] = old_chksum; + fprintf(fp, "%02X\n", new_chksum); + if(new_chksum != old_chksum) { + if(report_func) + report_func(LOG_ERR, "record #%d: new_chksum(%02X) != old_chksum(%02X)\n", + recordno, new_chksum, old_chksum); + return 0; + } + return 1; +} + +struct hexline *new_hexline(uint8_t datalen, uint16_t offset, uint8_t tt) +{ + struct hexline *hexline; + size_t allocsize; + + allocsize = sizeof(struct hexline) + datalen + 1; /* checksum byte */ + if((hexline = malloc(allocsize)) == NULL) { + if(report_func) + report_func(LOG_ERR, "No more memory\n"); + return NULL; + } + memset(hexline, 0, allocsize); + hexline->d.content.header.ll = datalen; + hexline->d.content.header.offset = offset; + hexline->d.content.header.tt = tt; + return hexline; +} + +static int append_hexline(struct hexdata *hexdata, char *buf) +{ + int ret; + unsigned int ll, offset, tt; + char *p; + struct hexline *hexline; + unsigned int i; + + if(hexdata->got_eof) { + if(report_func) + report_func(LOG_ERR, "Extranous data after EOF record\n"); + return -EINVAL; + } + if(hexdata->last_line >= hexdata->maxlines) { + if(report_func) + report_func(LOG_ERR, "Hexfile too large (maxline %d)\n", hexdata->maxlines); + return -ENOMEM; + } + ret = sscanf(buf, "%02X%04X%02X", &ll, &offset, &tt); + if(ret != 3) { + if(report_func) + report_func(LOG_ERR, "Bad line header (only %d items out of 3 parsed)\n", ret); + return -EINVAL; + } + switch(tt) { + case TT_DATA: + break; + case TT_EOF: + if(ll != 0) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EOF): Bad len = %d\n", + hexdata->last_line, tt, ll); + return -EINVAL; + } + if(offset != 0) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EOF): Bad offset = %d\n", + hexdata->last_line, tt, offset); + return -EINVAL; + } + hexdata->got_eof = 1; + break; + case TT_EXT_SEG: + if(ll != 2) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EXT_SEG): Bad len = %d\n", + hexdata->last_line, tt, ll); + return -EINVAL; + } + if(offset != 0) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EXT_SEG): Bad offset = %d\n", + hexdata->last_line, tt, offset); + return -EINVAL; + } + break; + case TT_START_SEG: + if(ll != 4) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(START_SEG): Bad len = %d\n", + hexdata->last_line, tt, ll); + return -EINVAL; + } + if(offset != 0) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(START_SEG): Bad offset = %d\n", + hexdata->last_line, tt, offset); + return -EINVAL; + } + break; + case TT_EXT_LIN: + if(ll != 2) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EXT_LIN): Bad len = %d\n", + hexdata->last_line, tt, ll); + return -EINVAL; + } + if(offset != 0) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EXT_LIN): Bad offset = %d\n", + hexdata->last_line, tt, ll); + return -EINVAL; + } + break; + case TT_START_LIN: /* Unimplemented */ + if(ll != 4) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EXT_LIN): Bad len = %d\n", + hexdata->last_line, tt, ll); + return -EINVAL; + } + if(offset != 0) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EXT_LIN): Bad offset = %d\n", + hexdata->last_line, tt, ll); + return -EINVAL; + } + break; + default: + if(report_func) + report_func(LOG_ERR, "%d: Unimplemented record type %d: %s\n", + hexdata->last_line, tt, buf); + return -EINVAL; + } + buf += 8; /* Skip header */ + if((hexline = new_hexline(ll, offset, tt)) == NULL) { + if(report_func) + report_func(LOG_ERR, "No more memory for hexfile lines\n"); + return -EINVAL; + } + p = buf; + for(i = 0; i < ll + 1; i++) { /* include checksum */ + unsigned int val; + + if((*p == '\0') || (*(p+1) == '\0')) { + if(report_func) + report_func(LOG_ERR, "Short data string '%s'\n", buf); + return -EINVAL; + } + ret = sscanf(p, "%02X", &val); + if(ret != 1) { + if(report_func) + report_func(LOG_ERR, "Bad data byte #%d\n", i); + return -EINVAL; + } + hexline->d.content.tt_data.data[i] = val; + p += 2; + } + if(hexline_checksum(hexline) != 0) { + if(report_func) { + report_func(LOG_ERR, "Bad checksum (%d instead of 0)\n", + hexline_checksum(hexline)); + dump_hexline(hexdata->last_line, hexline, stderr); + } + return -EINVAL; + } + hexdata->lines[hexdata->last_line] = hexline; + if(hexdata->got_eof) + return 0; + hexdata->last_line++; + return 1; +} + +void free_hexdata(struct hexdata *hexdata) +{ + if(hexdata) { + unsigned int i; + + for(i = 0; i < hexdata->maxlines; i++) + if(hexdata->lines[i] != NULL) + free(hexdata->lines[i]); + free(hexdata); + } +} + +int dump_hexfile(struct hexdata *hexdata, const char *outfile) +{ + FILE *fp; + unsigned int i; + + if(report_func) + report_func(LOG_INFO, "Dumping hex data into '%s'\n", outfile); + if(!outfile || strcmp(outfile, "-") == 0) + fp = stdout; + else if((fp = fopen(outfile, "w")) == NULL) { + perror(outfile); + exit(1); + } + for(i = 0; i <= hexdata->last_line; i++) { + struct hexline *line = hexdata->lines[i]; + if(!line) { + if(report_func) + report_func(LOG_ERR, "Missing line at #%d\n", i); + return -EINVAL; + } + if(!dump_hexline(i, line, fp)) + return -EINVAL; + } + return 0; +} + +int dump_hexfile2(struct hexdata *hexdata, const char *outfile, uint8_t maxwidth) +{ + FILE *fp; + uint8_t tt; + unsigned int i; + struct hexline *line; + + if(report_func) + report_func(LOG_INFO, + "Dumping hex data into '%s' (maxwidth=%d)\n", + outfile, maxwidth); + if(!outfile || strcmp(outfile, "-") == 0) + fp = stdout; + else if((fp = fopen(outfile, "w")) == NULL) { + perror(outfile); + exit(1); + } + if(maxwidth == 0) + maxwidth = UINT8_MAX; + for(i = 0; i <= hexdata->last_line; i++) { + int bytesleft = 0; + int extra_offset = 0; + int base_offset; + uint8_t *base_data; + + line = hexdata->lines[i]; + if(!line) { + if(report_func) + report_func(LOG_ERR, "Missing line at #%d\n", i); + return -EINVAL; + } + bytesleft = line->d.content.header.ll; + /* split the line into several lines */ + tt = line->d.content.header.tt; + base_offset = line->d.content.header.offset; + base_data = line->d.content.tt_data.data; + while (bytesleft > 0) { + struct hexline *extraline; + uint8_t new_chksum; + unsigned int curr_bytes = (bytesleft >= maxwidth) ? maxwidth : bytesleft; + + /* generate the new line */ + if((extraline = new_hexline(curr_bytes, base_offset + extra_offset, tt)) == NULL) { + if(report_func) + report_func(LOG_ERR, "No more memory for hexfile lines\n"); + return -EINVAL; + } + memcpy(extraline->d.content.tt_data.data, base_data + extra_offset, curr_bytes); + new_chksum = 0xFF - hexline_checksum(extraline) + 1; + extraline->d.content.tt_data.data[curr_bytes] = new_chksum; + /* print it */ + dump_hexline(i, extraline, fp); + /* cleanups */ + free(extraline); + extra_offset += curr_bytes; + bytesleft -= curr_bytes; + } + } + if(tt != TT_EOF) { + if(report_func) + report_func(LOG_ERR, "Missing EOF record\n"); + return -EINVAL; + } + dump_hexline(i, line, fp); + return 0; +} + +void process_comment(struct hexdata *hexdata, char buf[]) +{ + char *dollar_start; + char *dollar_end; + const char id_prefix[] = "Id: "; + char tmp[BUFSIZ]; + char *p; + int len; + + if(report_func) + report_func(LOG_INFO, "Comment: %s\n", buf + 1); + /* Search for RCS keywords */ + if((dollar_start = strchr(buf, '$')) == NULL) + return; + if((dollar_end = strchr(dollar_start + 1, '$')) == NULL) + return; + /* Crop the '$' signs */ + len = dollar_end - dollar_start; + len -= 2; + memcpy(tmp, dollar_start + 1, len); + tmp[len] = '\0'; + p = tmp; + if(strstr(tmp, id_prefix) == NULL) + return; + p += strlen(id_prefix); + if((p = strchr(p, ' ')) == NULL) + return; + p++; + snprintf(hexdata->version_info, BUFSIZ, "%s", p); + if((p = strchr(hexdata->version_info, ' ')) != NULL) + *p = '\0'; +} + +struct hexdata *parse_hexfile(const char *fname, unsigned int maxlines) +{ + FILE *fp; + struct hexdata *hexdata = NULL; + int datasize; + char buf[BUFSIZ]; + int line; + int dos_eof = 0; + int ret; + + assert(fname != NULL); + if(report_func) + report_func(LOG_INFO, "Parsing %s\n", fname); + datasize = sizeof(struct hexdata) + maxlines * sizeof(char *); + hexdata = (struct hexdata *)malloc(datasize); + if(!hexdata) { + if(report_func) + report_func(LOG_ERR, "Failed to allocate %d bytes for hexfile contents\n", datasize); + goto err; + } + memset(hexdata, 0, datasize); + hexdata->maxlines = maxlines; + if((fp = fopen(fname, "r")) == NULL) { + if(report_func) + report_func(LOG_ERR, "Failed to open hexfile '%s'\n", fname); + goto err; + } + snprintf(hexdata->fname, PATH_MAX, "%s", fname); + for(line = 1; fgets(buf, BUFSIZ, fp); line++) { + if(dos_eof) { + if(report_func) + report_func(LOG_ERR, "%s:%d - Got DOS EOF character before true EOF\n", fname, line); + goto err; + } + if(buf[0] == 0x1A && buf[1] == '\0') { /* DOS EOF char */ + dos_eof = 1; + continue; + } + chomp(buf); + if(buf[0] == '\0') { + if(report_func) + report_func(LOG_ERR, "%s:%d - Short line\n", fname, line); + goto err; + } + if(buf[0] == '#') { + process_comment(hexdata, buf); + continue; + } + if(buf[0] != ':') { + if(report_func) + report_func(LOG_ERR, "%s:%d - Line begins with 0x%X\n", fname, line, buf[0]); + goto err; + } + if((ret = append_hexline(hexdata, buf + 1)) < 0) { + if(report_func) + report_func(LOG_ERR, "%s:%d - Failed parsing.\n", fname, line); + goto err; + } + } + fclose(fp); + if(report_func) + report_func(LOG_INFO, "%s parsed OK\n", fname); + return hexdata; +err: + free_hexdata(hexdata); + return NULL; +} + +void dump_binary(struct hexdata *hexdata, const char *outfile) +{ + FILE *fp; + unsigned int i; + size_t len; + + if(report_func) + report_func(LOG_INFO, "Dumping binary data into '%s'\n", outfile); + if((fp = fopen(outfile, "w")) == NULL) { + perror(outfile); + exit(1); + } + for(i = 0; i < hexdata->maxlines; i++) { + struct hexline *hexline = hexdata->lines[i]; + + if(!hexline) + break; + switch(hexline->d.content.header.tt) { + case TT_EOF: + if(report_func) + report_func(LOG_INFO, "\ndump: good EOF record"); + break; + case TT_DATA: + if(report_func) + report_func(LOG_INFO, "dump: %6d\r", i); + len = hexline->d.content.header.ll; + if(fwrite(hexline->d.content.tt_data.data, 1, len, fp) != len) { + perror("write"); + exit(1); + } + break; + case TT_EXT_SEG: + case TT_START_SEG: + case TT_EXT_LIN: + case TT_START_LIN: + if(report_func) + report_func(LOG_INFO, + "\ndump(%d): ignored record type %d", + i, hexline->d.content.header.tt); + break; + default: + if(report_func) + report_func(LOG_ERR, "dump: Unknown record type %d\n", + hexline->d.content.header.tt); + exit(1); + } + } + if(report_func) + report_func(LOG_INFO, "\nDump finished\n"); + fclose(fp); +} + +void gen_hexline(const uint8_t *data, uint16_t addr, size_t len, FILE *output) +{ + struct hexline *hexline; + + if(!data) { + fprintf(output, ":%02X%04X%02XFF\n", 0, 0, TT_EOF); + return; + } + if((hexline = new_hexline(len, addr, (!data) ? TT_EOF : TT_DATA)) == NULL) { + if(report_func) + report_func(LOG_ERR, "No more memory\n"); + return; + } + if(data) + memcpy(&hexline->d.content.tt_data, data, len); + dump_hexline(0, hexline, output); + free(hexline); +} + +/* + * Algorithm lifted of sum(1) implementation from coreutils. + * We chose the default algorithm (BSD style). + */ +int bsd_checksum(struct hexdata *hexdata) +{ + unsigned int i; + size_t len; + int ck = 0; + + for(i = 0; i < hexdata->maxlines; i++) { + struct hexline *hexline = hexdata->lines[i]; + unsigned char *p; + + if(!hexline) + break; + if(hexline->d.content.header.tt == TT_EOF) + continue; + len = hexline->d.content.header.ll; + p = hexline->d.content.tt_data.data; + for(; len; p++, len--) { + ck = (ck >> 1) + ((ck & 1) << 15); + ck += *p; + ck &= 0xffff; /* Keep it within bounds. */ + } + } + return ck; +} diff --git a/xpp/hexfile.h b/xpp/hexfile.h new file mode 100644 index 0000000..27c71e7 --- /dev/null +++ b/xpp/hexfile.h @@ -0,0 +1,87 @@ +/* + * Written by Oron Peled + * Copyright (C) 2006, 2007, 2008, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef PARSE_HEXFILE_H +#define PARSE_HEXFILE_H + +#include +#include +#include +#include +#include +#define PACKED __attribute__((packed)) +#define ZERO_SIZE 0 + +/* Record types in hexfile */ +enum { + TT_DATA = 0, + TT_EOF = 1, + TT_EXT_SEG = 2, + TT_START_SEG = 3, + TT_EXT_LIN = 4, + TT_START_LIN = 5, + TT_NO_SUCH_TT +}; + +#pragma pack(1) +struct hexline { + union { + uint8_t raw[ZERO_SIZE]; + struct content { + struct header { + uint8_t ll; /* len */ + uint16_t offset; /* offset */ + uint8_t tt; /* type */ + } PACKED header; + struct tt_data { + uint8_t data[ZERO_SIZE]; + } tt_data; + } PACKED content; + } d; +} PACKED; +#pragma pack() + +struct hexdata { + unsigned int maxlines; + unsigned int last_line; + int got_eof; + char fname[PATH_MAX]; + char version_info[BUFSIZ]; + struct hexline *lines[ZERO_SIZE]; +}; + + +__BEGIN_DECLS + +typedef void (*parse_hexfile_report_func_t)(int level, const char *msg, ...); + +parse_hexfile_report_func_t parse_hexfile_set_reporting(parse_hexfile_report_func_t rf); +void free_hexdata(struct hexdata *hexdata); +struct hexdata *parse_hexfile(const char *fname, unsigned int maxlines); +int dump_hexfile(struct hexdata *hexdata, const char *outfile); +int dump_hexfile2(struct hexdata *hexdata, const char *outfile, uint8_t maxwidth); +void dump_binary(struct hexdata *hexdata, const char *outfile); +void gen_hexline(const uint8_t *data, uint16_t addr, size_t len, FILE *output); +int bsd_checksum(struct hexdata *hexdata); +__END_DECLS + +#endif diff --git a/xpp/lsdahdi b/xpp/lsdahdi new file mode 100755 index 0000000..2e68d44 --- /dev/null +++ b/xpp/lsdahdi @@ -0,0 +1,110 @@ +#! /usr/bin/perl -w +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use File::Basename; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); } + +use Dahdi; +use Dahdi::Span; +use Dahdi::Xpp; +use Dahdi::Xpp::Xbus; +use Dahdi::Xpp::Xpd; + +my @xbuses = Dahdi::Xpp::xbuses; +my @xpds = map { $_->xpds } @xbuses; + +foreach my $span (Dahdi::spans()) { + my $spanno = $span->num; + my $xpd = Dahdi::Xpp::xpd_of_span($span); + my @lines; + my $index = 0; + + @lines = @{$xpd->lines} if defined $xpd; + printf "### Span %2d: %s %s\n", $span->num, $span->name, $span->description; + foreach my $chan ($span->chans()) { + my %type_map = ( + OUT => 'Output', + IN => 'Input' + ); + my ($type) = map { $type_map{$_} or $_ } $chan->type || ("unknown"); + my $batt = ""; + $batt = "(battery)" if $chan->battery; + my @alarms = $chan->alarms; + my $alarm_str = join(" ", @alarms); + printf "%3d %-10s %-10s %s %s %s\n", + $chan->num, $type, $chan->signalling, $chan->info, $batt, $alarm_str; + $index++; + } +} + +__END__ + +=head1 NAME + +lsdahdi - List all Dahdi channels with their types and spans. + +=head1 SYNOPSIS + +lsdahdi + +=head1 DESCRIPTION + +Example output: + + ### Span 1: WCTDM/0 "Wildcard TDM400P REV E/F Board 1" + 1 FXO FXOLS (In use) + 2 FXS FXSKS + 3 FXS FXSKS + 4 FXS FXSKS + ### Span 2: XBUS-00/XPD-00 "Xorcom XPD #00/00: FXO" + 5 FXO FXSKS (In use) + 6 FXO FXSKS (In use) (no pcm) + 7 FXO FXSKS (In use) (no pcm) + 8 FXO FXSKS (In use) (no pcm) + 9 FXO FXSKS (In use) (no pcm) + 10 FXO FXSKS (In use) (no pcm) + 11 FXO FXSKS (In use) (no pcm) + 12 FXO FXSKS (In use) (no pcm) + ### Span 3: XBUS-00/XPD-10 "Xorcom XPD #00/10: FXO" + 13 FXO FXSKS (In use) (no pcm) + 14 FXO FXSKS (In use) (no pcm) + 15 FXO FXSKS (In use) (no pcm) + 16 FXO FXSKS (In use) (no pcm) + 17 FXO FXSKS (In use) (no pcm) + 18 FXO FXSKS (In use) (no pcm) + 19 FXO FXSKS (In use) (no pcm) + 20 FXO FXSKS (In use) (no pcm) + + ... + + ### Span 6: XBUS-01/XPD-00 "Xorcom XPD #01/00: FXS" + 37 FXS FXOLS (In use) + 38 FXS FXOLS (In use) (no pcm) + 39 FXS FXOLS (In use) (no pcm) + 40 FXS FXOLS (In use) (no pcm) + 41 FXS FXOLS (In use) (no pcm) + 42 FXS FXOLS (In use) (no pcm) + 43 FXS FXOLS (In use) (no pcm) + 44 FXS FXOLS (In use) (no pcm) + 45 Output FXOLS (In use) (no pcm) + 46 Output FXOLS (In use) (no pcm) + 47 Input FXOLS (In use) (no pcm) + 48 Input FXOLS (In use) (no pcm) + 49 Input FXOLS (In use) (no pcm) + 50 Input FXOLS (In use) (no pcm) + +The first column is the type of the channel (port, for an analog device) +and the second one is the signalling (if set). + +=head1 FILES + +lsdahdi is a somewhat glorified 'cat /proc/dahdi/*' . Unlike that +command, it sorts the spans with the proper order. It also formats the +output slightly differently. diff --git a/xpp/mpp.h b/xpp/mpp.h new file mode 100644 index 0000000..53ea81e --- /dev/null +++ b/xpp/mpp.h @@ -0,0 +1,202 @@ +#ifndef MPP_H +#define MPP_H +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* + * MPP - Managment Processor Protocol definitions + */ + +#include +#include +#include + +#ifdef __GNUC__ +#define PACKED __attribute__((packed)) +#else +#error "We do not know how your compiler packs structures" +#endif + +#define MK_PROTO_VERSION(major, minor) (((major) << 4) | (0x0F & (minor))) + +#define MPP_PROTOCOL_VERSION MK_PROTO_VERSION(1,4) +#define MPP_SUPPORTED_VERSION(x) ((x) == MK_PROTO_VERSION(1,3) || (x) == MK_PROTO_VERSION(1,4)) + +/* + * The eeprom_table is common to all eeprom types. + */ +#define LABEL_SIZE 8 +struct eeprom_table { + uint8_t source; /* C0 - small eeprom, C2 - large eeprom */ + uint16_t vendor; + uint16_t product; + uint16_t release; /* BCD encoded release */ + uint8_t config_byte; /* Must be 0 */ + uint8_t label[LABEL_SIZE]; +} PACKED; + +#define VERSION_LEN 6 +struct firmware_versions { + char usb[VERSION_LEN]; + char fpga[VERSION_LEN]; + char eeprom[VERSION_LEN]; +} PACKED; + +struct capabilities { + uint8_t ports_fxs; + uint8_t ports_fxo; + uint8_t ports_bri; + uint8_t ports_pri; + uint8_t extra_features; /* BIT(0) - TwinStar */ + uint8_t ports_echo; + uint8_t reserved[2]; + uint32_t timestamp; +} PACKED; + +#define CAP_EXTRA_TWINSTAR(c) ((c)->extra_features & 0x01) +#define CAP_EXTRA_TWINSTAR_SET(c) do {(c)->extra_features |= 0x01;} while (0) +#define CAP_EXTRA_TWINSTAR_CLR(c) do {(c)->extra_features &= ~0x01;} while (0) + +#define KEYSIZE 16 + +struct capkey { + uint8_t k[KEYSIZE]; +} PACKED; + +struct extrainfo { + char text[EXTRAINFO_SIZE]; +} PACKED; + +struct mpp_header { + uint16_t len; + uint16_t seq; + uint8_t op; /* MSB: 0 - to device, 1 - from device */ +} PACKED; + +enum mpp_ser_op { + SER_CARD_INFO_GET = 0x1, + SER_STAT_GET = 0x3, +/* Status bits */ +#define SER_STAT_WATCHDOG_READY(s) ((s) & 0x01) +#define SER_STAT_XPD_ALIVE(s) ((s) & 0x02) +}; + +/* Individual commands structure */ + +CMD_DEF(MPP, STATUS_GET); + + +CMD_DEF(MPP, STATUS_GET_REPLY, + uint8_t i2cs_data; + +#define STATUS_FPGA_LOADED(x) ((x) & 0x01) + uint8_t status; /* BIT(0) - FPGA is loaded */ + struct firmware_versions fw_versions; + ); + +CMD_DEF(MPP, EEPROM_SET, + struct eeprom_table data; + ); + +CMD_DEF(MPP, CAPS_GET); + +CMD_DEF(MPP, CAPS_GET_REPLY, + struct eeprom_table data; + struct capabilities capabilities; + struct capkey key; + ); + +CMD_DEF(MPP, CAPS_SET, + struct eeprom_table data; + struct capabilities capabilities; + struct capkey key; + ); + +CMD_DEF(MPP, EXTRAINFO_GET); + +CMD_DEF(MPP, EXTRAINFO_GET_REPLY, + struct extrainfo info; + ); + +CMD_DEF(MPP, EXTRAINFO_SET, + struct extrainfo info; + ); + +CMD_DEF(MPP, RENUM); + +CMD_DEF(MPP, EEPROM_BLK_RD, + uint16_t offset; + uint16_t len; + ); + +CMD_DEF(MPP, EEPROM_BLK_RD_REPLY, + uint16_t offset; + uint8_t data[0]; + ); + +CMD_DEF(MPP, DEV_SEND_START, + uint8_t dest; + char ihex_version[VERSION_LEN]; + ); + +CMD_DEF(MPP, DEV_SEND_END); + +CMD_DEF(MPP, DEV_SEND_SEG, + uint16_t offset; + uint8_t data[0]; + ); + +CMD_DEF(MPP, RESET); +CMD_DEF(MPP, HALF_RESET); + +CMD_DEF(MPP, SER_SEND, + uint8_t data[0]; + ); + +CMD_DEF(MPP, SER_RECV, + uint8_t data[0]; + ); + +CMD_DEF(MPP, TWS_WD_MODE_SET, + uint8_t wd_active; + ); + +CMD_DEF(MPP, TWS_WD_MODE_GET); +CMD_DEF(MPP, TWS_WD_MODE_GET_REPLY, + uint8_t wd_active; + ); + +CMD_DEF(MPP, TWS_PORT_SET, + uint8_t portnum; + ); + +CMD_DEF(MPP, TWS_PORT_GET); +CMD_DEF(MPP, TWS_PORT_GET_REPLY, + uint8_t portnum; + ); + +CMD_DEF(MPP, TWS_PWR_GET); +CMD_DEF(MPP, TWS_PWR_GET_REPLY, + uint8_t power; + ); + +#endif /* MPP_H */ diff --git a/xpp/mpptalk.c b/xpp/mpptalk.c new file mode 100644 index 0000000..e49c3cd --- /dev/null +++ b/xpp/mpptalk.c @@ -0,0 +1,956 @@ +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include "hexfile.h" +#include "astribank_usb.h" +#include "mpp.h" +#include "mpptalk.h" +#include +#include +#include + +static const char rcsid[] = "$Id$"; + +#define DBG_MASK 0x02 + +const char *ack_status_msg(uint8_t status) +{ + const static char *msgs[] = { + [STAT_OK] = "Acknowledges previous command", + [STAT_FAIL] = "Last command failed", + [STAT_RESET_FAIL] = "Reset failed", + [STAT_NODEST] = "No destination is selected", + [STAT_MISMATCH] = "Data mismatch", + [STAT_NOACCESS] = "No access", + [STAT_BAD_CMD] = "Bad command", + [STAT_TOO_SHORT] = "Packet is too short", + [STAT_ERROFFS] = "Offset error", + [STAT_NOCODE] = "Source was not burned before", + [STAT_NO_LEEPROM] = "Large EEPROM was not found", + [STAT_NO_EEPROM] = "No EEPROM was found", + [STAT_WRITE_FAIL] = "Writing to device failed", + [STAT_FPGA_ERR] = "FPGA error", + [STAT_KEY_ERR] = "Bad Capabilities Key", + [STAT_NOCAPS_ERR] = "No matching capability", + [STAT_NOPWR_ERR] = "No power on USB connector", + [STAT_CAPS_FPGA_ERR] = "Setting of the capabilities while FPGA is loaded", + }; + if(status > sizeof(msgs)/sizeof(msgs[0])) + return "ERROR CODE TOO LARGE"; + if(!msgs[status]) + return "MISSING ERROR CODE"; + return msgs[status]; +} + +const char *eeprom_type2str(int et) +{ + const static char *msgs[] = { + [EEPROM_TYPE_NONE] = "NONE", + [EEPROM_TYPE_SMALL] = "SMALL", + [EEPROM_TYPE_LARGE] = "LARGE", + [EEPROM_TYPE_UNUSED] = "UNUSED", + }; + if(et > sizeof(msgs)/sizeof(msgs[0])) + return NULL; + return msgs[et]; +}; + +const char *dev_dest2str(int dest) +{ + const static char *msgs[] = { + [DEST_NONE] = "NONE", + [DEST_FPGA] = "FPGA", + [DEST_EEPROM] = "EEPROM", + }; + if(dest > sizeof(msgs)/sizeof(msgs[0])) + return NULL; + return msgs[dest]; +}; + +union XTALK_PDATA(MPP) { + MEMBER(MPP, STATUS_GET); + MEMBER(MPP, STATUS_GET_REPLY); + MEMBER(MPP, EEPROM_SET); + MEMBER(MPP, CAPS_GET); + MEMBER(MPP, CAPS_GET_REPLY); + MEMBER(MPP, CAPS_SET); + MEMBER(MPP, EXTRAINFO_GET); + MEMBER(MPP, EXTRAINFO_GET_REPLY); + MEMBER(MPP, EXTRAINFO_SET); + MEMBER(MPP, RENUM); + MEMBER(MPP, EEPROM_BLK_RD); + MEMBER(MPP, EEPROM_BLK_RD_REPLY); + MEMBER(MPP, DEV_SEND_SEG); + MEMBER(MPP, DEV_SEND_START); + MEMBER(MPP, DEV_SEND_END); + MEMBER(MPP, RESET); + MEMBER(MPP, HALF_RESET); + MEMBER(MPP, SER_SEND); + MEMBER(MPP, SER_RECV); + /* Twinstar */ + MEMBER(MPP, TWS_WD_MODE_SET); + MEMBER(MPP, TWS_WD_MODE_GET); + MEMBER(MPP, TWS_WD_MODE_GET_REPLY); + MEMBER(MPP, TWS_PORT_SET); + MEMBER(MPP, TWS_PORT_GET); + MEMBER(MPP, TWS_PORT_GET_REPLY); + MEMBER(MPP, TWS_PWR_GET); + MEMBER(MPP, TWS_PWR_GET_REPLY); +} PACKED members; + +struct xtalk_protocol astribank_proto = { + .name = "ABNK", + .proto_version = 0x14, + .commands = { + CMD_SEND(MPP, STATUS_GET), + CMD_RECV(MPP, STATUS_GET_REPLY, NULL), + CMD_SEND(MPP, EEPROM_SET), + CMD_SEND(MPP, CAPS_GET), + CMD_RECV(MPP, CAPS_GET_REPLY, NULL), + CMD_SEND(MPP, CAPS_SET), + CMD_SEND(MPP, EXTRAINFO_GET), + CMD_RECV(MPP, EXTRAINFO_GET_REPLY, NULL), + CMD_SEND(MPP, EXTRAINFO_SET), + CMD_SEND(MPP, RENUM), + CMD_SEND(MPP, EEPROM_BLK_RD), + CMD_RECV(MPP, EEPROM_BLK_RD_REPLY, NULL), + CMD_SEND(MPP, DEV_SEND_SEG), + CMD_SEND(MPP, DEV_SEND_START), + CMD_SEND(MPP, DEV_SEND_END), + CMD_SEND(MPP, RESET), + CMD_SEND(MPP, HALF_RESET), + CMD_SEND(MPP, SER_SEND), + CMD_SEND(MPP, SER_RECV), + /* Twinstar */ + CMD_SEND(MPP, TWS_WD_MODE_SET), + CMD_SEND(MPP, TWS_WD_MODE_GET), + CMD_RECV(MPP, TWS_WD_MODE_GET_REPLY, NULL), + CMD_SEND(MPP, TWS_PORT_SET), + CMD_SEND(MPP, TWS_PORT_GET), + CMD_RECV(MPP, TWS_PORT_GET_REPLY, NULL), + CMD_SEND(MPP, TWS_PWR_GET), + CMD_RECV(MPP, TWS_PWR_GET_REPLY, NULL), + }, + .ack_statuses = { + } +}; + +struct cmd_queue { + struct cmd_queue *next; + struct cmd_queue *prev; + struct xtalk_command *cmd; +}; + +static struct cmd_queue output_queue = { + .next = &output_queue, + .prev = &output_queue, + .cmd = NULL + }; + +void dump_command(struct xtalk_command *cmd) +{ + uint16_t len; + int i; + + len = cmd->header.len; + if(len < sizeof(struct mpp_header)) { + ERR("Command too short (%d)\n", len); + return; + } + INFO("DUMP: OP=0x%X len=%d seq=%d\n", + cmd->header.op, cmd->header.len, cmd->header.seq); + for(i = 0; i < len - sizeof(struct mpp_header); i++) { + INFO(" %2d. 0x%X\n", i, cmd->alt.raw_data[i]); + } +} + + +static int set_ihex_version(char *dst, const char *src) +{ + memcpy(dst, src, VERSION_LEN); + return 0; +} + +/* + * Protocol Commands + */ + +int mpp_status_query(struct astribank_device *astribank) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_STATUS_GET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + astribank->eeprom_type = 0x3 & (CMD_FIELD(reply, MPP, STATUS_GET_REPLY, i2cs_data) >> 3); + astribank->status = CMD_FIELD(reply, MPP, STATUS_GET_REPLY, status); + astribank->fw_versions = CMD_FIELD(reply, MPP, STATUS_GET_REPLY, fw_versions); + DBG("EEPROM TYPE: %02x\n", astribank->eeprom_type); + DBG("FPGA Firmware: %s\n", (astribank->status & 0x1) ? "Loaded" : "Empty"); + DBG("Firmware Versions: USB='%s' FPGA='%s' EEPROM='%s'\n", + astribank->fw_versions.usb, + astribank->fw_versions.fpga, + astribank->fw_versions.eeprom); + free_command(reply); + return ret; +} + +int mpp_eeprom_set(struct astribank_device *astribank, const struct eeprom_table *et) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_EEPROM_SET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + memcpy(&CMD_FIELD(cmd, MPP, EEPROM_SET, data), et, sizeof(*et)); + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + free_command(reply); + return 0; +} + +int mpp_renumerate(struct astribank_device *astribank) +{ + struct xtalk_command *cmd; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_RENUM, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + ret = process_command(xtalk_dev, cmd, NULL); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + return 0; +} + +int mpp_caps_get(struct astribank_device *astribank, + struct eeprom_table *eeprom_table, + struct capabilities *capabilities, + struct capkey *key) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_CAPS_GET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + assert(reply->header.op == MPP_CAPS_GET_REPLY); + if(eeprom_table) { + memcpy(eeprom_table, (void *)&CMD_FIELD(reply, MPP, CAPS_GET_REPLY, data), sizeof(*eeprom_table)); + } + if(capabilities) { + const struct capabilities *cap = &CMD_FIELD(reply, MPP, CAPS_GET_REPLY, capabilities); + + memcpy(capabilities, cap, sizeof(*capabilities)); + } + if(key) { + const struct capkey *k = &CMD_FIELD(reply, MPP, CAPS_GET_REPLY, key); + + memcpy(key, k, sizeof(*key)); + } + free_command(reply); + return 0; +} + +int mpp_caps_set(struct astribank_device *astribank, + const struct eeprom_table *eeprom_table, + const struct capabilities *capabilities, + const struct capkey *key) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_CAPS_SET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + memcpy(&CMD_FIELD(cmd, MPP, CAPS_SET, data), eeprom_table, sizeof(*eeprom_table)); + memcpy(&CMD_FIELD(cmd, MPP, CAPS_SET, capabilities), capabilities, sizeof(*capabilities)); + memcpy(&CMD_FIELD(cmd, MPP, CAPS_SET, key), key, sizeof(*key)); + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + free_command(reply); + return 0; +} + +int mpp_extrainfo_get(struct astribank_device *astribank, struct extrainfo *info) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_EXTRAINFO_GET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + assert(reply->header.op == MPP_EXTRAINFO_GET_REPLY); + if(info) { + int i; + + memcpy(info, (void *)&CMD_FIELD(reply, MPP, EXTRAINFO_GET_REPLY, info), sizeof(*info)); + /* + * clean non-printing characters + */ + for (i = sizeof(*info) - 1; i >= 0; i--) { + if (info->text[i] != (char)0xFF) + break; + info->text[i] = '\0'; + } + } + free_command(reply); + return 0; +} + +int mpp_extrainfo_set(struct astribank_device *astribank, const struct extrainfo *info) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_EXTRAINFO_SET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + memcpy(&CMD_FIELD(cmd, MPP, EXTRAINFO_SET, info), info, sizeof(*info)); + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + free_command(reply); + return 0; +} + +int mpp_eeprom_blk_rd(struct astribank_device *astribank, uint8_t *buf, uint16_t offset, uint16_t len) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + int size; + + DBG("len = %d, offset = %d\n", len, offset); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_EEPROM_BLK_RD, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + CMD_FIELD(cmd, MPP, EEPROM_BLK_RD, len) = len; + CMD_FIELD(cmd, MPP, EEPROM_BLK_RD, offset) = offset; + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + size = ret; + goto out; + } + size = reply->header.len - sizeof(struct mpp_header) - sizeof(XTALK_STRUCT(MPP, EEPROM_BLK_RD_REPLY)); + INFO("size=%d offset=0x%X\n", size, CMD_FIELD(reply, MPP, EEPROM_BLK_RD_REPLY, offset)); + dump_packet(LOG_DEBUG, DBG_MASK, "BLK_RD", (char *)reply, ret); + if(size > len) { + ERR("Truncating reply (was %d, now %d)\n", size, len); + size = len; + } + memcpy(buf, CMD_FIELD(reply, MPP, EEPROM_BLK_RD_REPLY, data), size); +out: + free_command(reply); + return size; +} + +int mpp_send_start(struct astribank_device *astribank, int dest, const char *ihex_version) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply = NULL; + struct xtalk_device *xtalk_dev; + int ret = 0; + + DBG("dest = %s ihex_version = '%s'\n", dev_dest2str(dest), ihex_version); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_DEV_SEND_START, 0)) == NULL) { + ERR("new_command failed\n"); + ret = -ENOMEM; + goto out; + } + CMD_FIELD(cmd, MPP, DEV_SEND_START, dest) = dest; + set_ihex_version(CMD_FIELD(cmd, MPP, DEV_SEND_START, ihex_version), ihex_version); + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + goto out; + } +out: + if(reply) + free_command(reply); + astribank->burn_state = (ret == 0) + ? BURN_STATE_STARTED + : BURN_STATE_FAILED; + return ret; +} + +int mpp_send_end(struct astribank_device *astribank) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply = NULL; + struct xtalk_device *xtalk_dev; + int ret = 0; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_DEV_SEND_END, 0)) == NULL) { + ERR("new_command failed\n"); + ret = -ENOMEM; + goto out; + } + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + goto out; + } +out: + if(reply) + free_command(reply); + astribank->burn_state = (ret == 0) + ? BURN_STATE_ENDED + : BURN_STATE_FAILED; + return ret; +} + +int mpp_send_seg(struct astribank_device *astribank, const uint8_t *data, uint16_t offset, uint16_t len) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if(!astribank->burn_state == BURN_STATE_STARTED) { + ERR("Tried to send a segment while burn_state=%d\n", + astribank->burn_state); + return -EINVAL; + } + DBG("len = %d, offset = %d (0x%02X, 0x%02X)\n", len, offset, *data, *(data + 1)); + if((cmd = new_command(xtalk_dev, MPP_DEV_SEND_SEG, len)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + CMD_FIELD(cmd, MPP, DEV_SEND_SEG, offset) = offset; + memcpy(CMD_FIELD(cmd, MPP, DEV_SEND_SEG, data), data, len); +#if 0 + { + FILE *fp; + if((fp = fopen("seg_data.bin", "a")) == NULL) { + perror("seg_data.bin"); + exit(1); + } + if(fwrite(CMD_FIELD(cmd, MPP, DEV_SEND_SEG, data), len, 1, fp) != 1) { + perror("fwrite"); + exit(1); + } + fclose(fp); + } +#endif + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + free_command(reply); + return 0; +} + +int mpp_reset(struct astribank_device *astribank, int full_reset) +{ + struct xtalk_command *cmd; + struct xtalk_device *xtalk_dev; + int ret; + int op = (full_reset) ? MPP_RESET: MPP_HALF_RESET; + + DBG("full = %s\n", (full_reset) ? "YES" : "NO"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, op, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + ret = process_command(xtalk_dev, cmd, NULL); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + return 0; +} + +int mpp_serial_cmd(struct astribank_device *astribank, const uint8_t *in, uint8_t *out, uint16_t len) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + uint8_t *data; + + DBG("len=%d\n", len); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_SER_SEND, len)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + data = CMD_FIELD(cmd, MPP, SER_SEND, data); + memcpy(data, in, len); + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + assert(reply->header.op == MPP_SER_RECV); + data = CMD_FIELD(reply, MPP, SER_RECV, data); + memcpy(out, data, len); + free_command(reply); + return 0; +} + +int mpps_card_info(struct astribank_device *astribank, int unit, uint8_t *card_type, uint8_t *card_status) +{ + /* + * Serial commands must have equal send/receive size + */ + struct card_info_command { + uint8_t ser_op; + uint8_t addr; + uint8_t card_full_type; /* (type << 4 | subtype) */ + uint8_t card_status; /* BIT(0) - PIC burned */ + } PACKED; + struct card_info_command ci_send; + struct card_info_command ci_recv; + int ret; + + memset(&ci_send, 0, sizeof(ci_send)); + memset(&ci_recv, 0, sizeof(ci_recv)); + ci_send.ser_op = SER_CARD_INFO_GET; + ci_send.addr = (unit << 4); /* low nibble is subunit */ + ret = mpp_serial_cmd(astribank, + (uint8_t *)&ci_send, + (uint8_t *)&ci_recv, + sizeof(struct card_info_command)); + if (ret < 0) + return ret; + *card_type = ci_recv.card_full_type; + *card_status = ci_recv.card_status; + return 0; +} + +int mpps_stat(struct astribank_device *astribank, int unit, uint8_t *fpga_configuration, uint8_t *status) +{ + /* + * Serial commands must have equal send/receive size + */ + struct fpga_stat_command { + uint8_t ser_op; + uint8_t fpga_configuration; + uint8_t status; /* BIT(0) - Watchdog timer status */ + } PACKED; + struct fpga_stat_command fs_send; + struct fpga_stat_command fs_recv; + int ret; + + memset(&fs_send, 0, sizeof(fs_send)); + memset(&fs_recv, 0, sizeof(fs_recv)); + fs_send.ser_op = SER_STAT_GET; + ret = mpp_serial_cmd(astribank, + (uint8_t *)&fs_send, + (uint8_t *)&fs_recv, + sizeof(struct fpga_stat_command)); + if(ret < 0) + return ret; + *fpga_configuration = fs_recv.fpga_configuration; + *status = fs_recv.status; + return 0; +} + +int mpp_tws_watchdog(struct astribank_device *astribank) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_TWS_WD_MODE_GET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + ret = CMD_FIELD(reply, MPP, TWS_WD_MODE_GET_REPLY, wd_active); + DBG("wd_active=0x%X\n", ret); + free_command(reply); + return ret == 1; +} + +int mpp_tws_setwatchdog(struct astribank_device *astribank, int yes) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("%s\n", (yes) ? "YES" : "NO"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_TWS_WD_MODE_SET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + CMD_FIELD(cmd, MPP, TWS_WD_MODE_SET, wd_active) = (yes) ? 1 : 0; + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + free_command(reply); + return 0; +} + +int mpp_tws_powerstate(struct astribank_device *astribank) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_TWS_PWR_GET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + ret = CMD_FIELD(reply, MPP, TWS_PWR_GET_REPLY, power); + DBG("power=0x%X\n", ret); + free_command(reply); + return ret; +} + +int mpp_tws_portnum(struct astribank_device *astribank) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_TWS_PORT_GET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + ret = CMD_FIELD(reply, MPP, TWS_PORT_GET_REPLY, portnum); + DBG("portnum=0x%X\n", ret); + free_command(reply); + return ret; +} + +int mpp_tws_setportnum(struct astribank_device *astribank, uint8_t portnum) +{ + struct xtalk_command *cmd; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if(portnum >= 2) { + ERR("Invalid portnum (%d)\n", portnum); + return -EINVAL; + } + if((cmd = new_command(xtalk_dev, MPP_TWS_PORT_SET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + CMD_FIELD(cmd, MPP, TWS_PORT_SET, portnum) = portnum; + ret = process_command(xtalk_dev, cmd, NULL); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + return 0; +} + +/* Adapters for xusb ops */ +static inline int xusb_close_func(void *priv) +{ + return xusb_close((struct xusb *)priv); +} + +static inline int xusb_send_func(void *priv, void *data, size_t len, int timeout) +{ + return xusb_send((struct xusb *)priv, data, len, timeout); +} + +static inline int xusb_recv_func(void *priv, void *data, size_t maxlen, int timeout) +{ + return xusb_recv((struct xusb *)priv, data, maxlen, timeout); +} + + +static struct xtalk_ops xusb_ops = { + .send_func = xusb_send_func, + .recv_func = xusb_recv_func, + .close_func = xusb_close_func, +}; + +/* + * Wrappers + */ + +struct astribank_device *mpp_init(const char devpath[], int iface_num) +{ + struct astribank_device *astribank = NULL; + struct xtalk_device *xtalk_dev = NULL; + struct xusb *xusb = NULL; + int packet_size; + int ret; + + DBG("devpath='%s' iface_num=%d\n", devpath, iface_num); + if((astribank = astribank_open(devpath, iface_num)) == NULL) { + ERR("Opening astribank failed\n"); + goto err; + } + xusb = astribank->xusb; + packet_size = xusb_packet_size(xusb); + if((xtalk_dev = xtalk_new(&xusb_ops, packet_size, xusb)) == NULL) { + ERR("Allocating new XTALK device failed\n"); + goto err; + } + astribank->xtalk_dev = xtalk_dev; + ret = xtalk_set_protocol(xtalk_dev, &astribank_proto); + if(ret < 0) { + ERR("MPP Protocol registration failed: %d\n", ret); + goto err; + } + ret = xtalk_proto_query(xtalk_dev); + if(ret < 0) { + ERR("Protocol handshake failed: %d\n", ret); + goto err; + } + ret = mpp_status_query(astribank); + if(ret < 0) { + ERR("Status query failed: %d\n", ret); + goto err; + } + return astribank; + +err: + if (astribank) { + astribank_close(astribank, 0); + astribank = NULL; + } + if(xtalk_dev) { + xtalk_delete(xtalk_dev); + xtalk_dev = NULL; + } + return NULL; +} + +void mpp_exit(struct astribank_device *astribank) +{ + DBG("\n"); + astribank_close(astribank, 0); +} + +/* + * data structures + */ + +void show_eeprom(const struct eeprom_table *eprm, FILE *fp) +{ + int rmajor = (eprm->release >> 8) & 0xFF; + int rminor = eprm->release & 0xFF;; + char buf[BUFSIZ]; + + memset(buf, 0, LABEL_SIZE + 1); + memcpy(buf, eprm->label, LABEL_SIZE); + fprintf(fp, "EEPROM: %-15s: 0x%02X\n", "Source", eprm->source); + fprintf(fp, "EEPROM: %-15s: 0x%04X\n", "Vendor", eprm->vendor); + fprintf(fp, "EEPROM: %-15s: 0x%04X\n", "Product", eprm->product); + fprintf(fp, "EEPROM: %-15s: %d.%d\n", "Release", rmajor, rminor); + fprintf(fp, "EEPROM: %-15s: 0x%02X\n", "Config", eprm->config_byte); + fprintf(fp, "EEPROM: %-15s: '%s'\n", "Label", buf); +} + +void show_capabilities(const struct capabilities *capabilities, FILE *fp) +{ + fprintf(fp, "Capabilities: FXS ports: %2d\n", capabilities->ports_fxs); + fprintf(fp, "Capabilities: FXO ports: %2d\n", capabilities->ports_fxo); + fprintf(fp, "Capabilities: BRI ports: %2d\n", capabilities->ports_bri); + fprintf(fp, "Capabilities: PRI ports: %2d\n", capabilities->ports_pri); + fprintf(fp, "Capabilities: ECHO ports: %2d\n", capabilities->ports_echo); + fprintf(fp, "Capabilities: TwinStar : %s\n", + (CAP_EXTRA_TWINSTAR(capabilities)) ? "Yes" : "No"); +} + +void show_astribank_status(struct astribank_device *astribank, FILE *fp) +{ + char version_buf[BUFSIZ]; + int is_loaded = STATUS_FPGA_LOADED(astribank->status); + + fprintf(fp, "Astribank: EEPROM : %s\n", + eeprom_type2str(astribank->eeprom_type)); + fprintf(fp, "Astribank: FPGA status : %s\n", + is_loaded ? "Loaded" : "Empty"); + if(is_loaded) { + memset(version_buf, 0, sizeof(version_buf)); + memcpy(version_buf, astribank->fw_versions.fpga, VERSION_LEN); + fprintf(fp, "Astribank: FPGA version: %s\n", + version_buf); + } +} + +void show_extrainfo(const struct extrainfo *extrainfo, FILE *fp) +{ + char buf[EXTRAINFO_SIZE + 1]; + + memcpy(buf, extrainfo->text, EXTRAINFO_SIZE); + buf[EXTRAINFO_SIZE] = '\0'; /* assure null termination */ + fprintf(fp, "Extrainfo: : '%s'\n", buf); +} + +int twinstar_show(struct astribank_device *astribank, FILE *fp) +{ + int watchdog; + int powerstate; + int portnum; + int i; + + if(!astribank_has_twinstar(astribank)) { + fprintf(fp, "TwinStar: NO\n"); + return 0; + } + if((watchdog = mpp_tws_watchdog(astribank)) < 0) { + ERR("Failed getting TwinStar information\n"); + return watchdog; + } + if((powerstate = mpp_tws_powerstate(astribank)) < 0) { + ERR("Failed getting TwinStar powerstate\n"); + return powerstate; + } + if((portnum = mpp_tws_portnum(astribank)) < 0) { + ERR("Failed getting TwinStar portnum\n"); + return portnum; + } + fprintf(fp, "TwinStar: Connected to : USB-%1d\n", portnum); + fprintf(fp, "TwinStar: Watchdog : %s\n", + (watchdog) ? "on-guard" : "off-guard"); + for(i = 0; i < 2; i++) { + int pw = (1 << i) & powerstate; + + fprintf(fp, "TwinStar: USB-%1d POWER : %s\n", + i, (pw) ? "ON" : "OFF"); + } + return 0; +} diff --git a/xpp/mpptalk.h b/xpp/mpptalk.h new file mode 100644 index 0000000..49db037 --- /dev/null +++ b/xpp/mpptalk.h @@ -0,0 +1,85 @@ +#ifndef MPP_FUNCS_H +#define MPP_FUNCS_H +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include + +#include "mpp.h" +#include "astribank_usb.h" + +struct astribank_device; +struct eeprom_table; +struct extrainfo; +struct capabilities; +struct capkey; + +#define TIMEOUT 6000 + +/* high-level */ +struct astribank_device *mpp_init(const char devpath[], int iface_num); +void mpp_exit(struct astribank_device *astribank); +int mpp_proto_query(struct astribank_device *astribank); +int mpp_status_query(struct astribank_device *astribank); +int mpp_eeprom_set(struct astribank_device *astribank, const struct eeprom_table *et); +int mpp_renumerate(struct astribank_device *astribank); +int mpp_caps_get(struct astribank_device *astribank, + struct eeprom_table *et, + struct capabilities *cap, + struct capkey *key); +int mpp_caps_set(struct astribank_device *astribank, + const struct eeprom_table *eeprom_table, + const struct capabilities *capabilities, + const struct capkey *key); +int mpp_extrainfo_get(struct astribank_device *astribank, struct extrainfo *info); +int mpp_extrainfo_set(struct astribank_device *astribank, const struct extrainfo *info); +int mpp_eeprom_blk_rd(struct astribank_device *astribank, uint8_t *buf, uint16_t offset, uint16_t len); +int mpp_send_start(struct astribank_device *astribank, int dest, const char *ihex_version); +int mpp_send_end(struct astribank_device *astribank); +int mpp_send_seg(struct astribank_device *astribank, const uint8_t *data, uint16_t offset, uint16_t len); +int mpp_reset(struct astribank_device *astribank, int full_reset); +int mpp_serial_cmd(struct astribank_device *astribank, const uint8_t *in, uint8_t *out, uint16_t len); +void show_eeprom(const struct eeprom_table *eprm, FILE *fp); +void show_capabilities(const struct capabilities *capabilities, FILE *fp); +void show_astribank_status(struct astribank_device *astribank, FILE *fp); +void show_extrainfo(const struct extrainfo *extrainfo, FILE *fp); +int twinstar_show(struct astribank_device *astribank, FILE *fp); + +/* + * Serial commands to FPGA + */ +int mpps_card_info(struct astribank_device *astribank, int unit, uint8_t *card_type, uint8_t *card_status); +int mpps_stat(struct astribank_device *astribank, int unit, uint8_t *maincard_version, uint8_t *status); + +/* + * Twinstar + */ +int mpp_tws_watchdog(struct astribank_device *astribank); +int mpp_tws_setwatchdog(struct astribank_device *astribank, int yes); +int mpp_tws_powerstate(struct astribank_device *astribank); +int mpp_tws_portnum(struct astribank_device *astribank); +int mpp_tws_setportnum(struct astribank_device *astribank, uint8_t portnum); + +const char *dev_dest2str(int dest); + +#endif /* MPP_FUNCS_H */ diff --git a/xpp/mpptalk_defs.h b/xpp/mpptalk_defs.h new file mode 100644 index 0000000..bc0b83b --- /dev/null +++ b/xpp/mpptalk_defs.h @@ -0,0 +1,113 @@ +#ifndef MPPTALK_DEFS_H +#define MPPTALK_DEFS_H +/* + * Written by Oron Peled + * Copyright (C) 2008,2009,2010 Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +/* + * MPP - Managment Processor Protocol definitions + */ + +/* + * OP Codes: + * MSB of op signifies a reply from device + */ +#define MPP_RENUM 0x0B /* Trigger USB renumeration */ +#define MPP_EEPROM_SET 0x0D + +/* AB capabilities */ +#define MPP_CAPS_GET 0x0E +#define MPP_CAPS_GET_REPLY 0x8E +#define MPP_CAPS_SET 0x0F + +#define MPP_DEV_SEND_START 0x05 +#define MPP_DEV_SEND_SEG 0x07 +#define MPP_DEV_SEND_END 0x09 + +/* Astribank Status */ +#define MPP_STATUS_GET 0x11 +#define MPP_STATUS_GET_REPLY 0x91 +#define MPP_STATUS_GET_REPLY_V13 0x91 /* backward compat */ + +/* Get extra vendor information */ +#define MPP_EXTRAINFO_GET 0x13 +#define MPP_EXTRAINFO_GET_REPLY 0x93 +#define MPP_EXTRAINFO_SET 0x15 /* Set extra vendor information */ + +#define MPP_EEPROM_BLK_RD 0x27 +#define MPP_EEPROM_BLK_RD_REPLY 0xA7 + +#define MPP_SER_SEND 0x37 +#define MPP_SER_RECV 0xB7 + +#define MPP_RESET 0x45 /* Reset both FPGA and USB firmwares */ +#define MPP_HALF_RESET 0x47 /* Reset only FPGA firmware */ + +/* Twinstar */ +#define MPP_TWS_WD_MODE_SET 0x31 /* Set watchdog off/on guard */ +#define MPP_TWS_WD_MODE_GET 0x32 /* Current watchdog mode */ +#define MPP_TWS_WD_MODE_GET_REPLY 0xB2 /* Current watchdog mode */ +#define MPP_TWS_PORT_SET 0x34 /* USB-[0/1] */ +#define MPP_TWS_PORT_GET 0x35 /* USB-[0/1] */ +#define MPP_TWS_PORT_GET_REPLY 0xB5 /* USB-[0/1] */ +#define MPP_TWS_PWR_GET 0x36 /* Power: bits -> USB ports */ +#define MPP_TWS_PWR_GET_REPLY 0xB6 /* Power: bits -> USB ports */ + +/* + * Statuses + */ +#define STAT_OK 0x00 /* acknowledges previous command */ +#define STAT_FAIL 0x01 /* Last command failed */ +#define STAT_RESET_FAIL 0x02 /* reset failed */ +#define STAT_NODEST 0x03 /* No destination is selected */ +#define STAT_MISMATCH 0x04 /* Data mismatch */ +#define STAT_NOACCESS 0x05 /* No access */ +#define STAT_BAD_CMD 0x06 /* Bad command */ +#define STAT_TOO_SHORT 0x07 /* Packet is too short */ +#define STAT_ERROFFS 0x08 /* Offset error */ +#define STAT_NOCODE 0x09 /* Source was not burned before */ +#define STAT_NO_LEEPROM 0x0A /* Large EEPROM was not found */ +#define STAT_NO_EEPROM 0x0B /* No EEPROM was found */ +#define STAT_WRITE_FAIL 0x0C /* Writing to device failed */ +#define STAT_FPGA_ERR 0x0D /* FPGA error */ +#define STAT_KEY_ERR 0x0E /* Bad Capabilities Key */ +#define STAT_NOCAPS_ERR 0x0F /* No matching capability */ +#define STAT_NOPWR_ERR 0x10 /* No power on USB connector */ +#define STAT_CAPS_FPGA_ERR 0x11 /* Setting of the capabilities while FPGA is loaded */ + +/* EEPROM_QUERY: i2cs(ID1, ID0) */ +enum eeprom_type { + EEPROM_TYPE_NONE = 0, + EEPROM_TYPE_SMALL = 1, + EEPROM_TYPE_LARGE = 2, + EEPROM_TYPE_UNUSED = 3, +}; + +enum dev_dest { + DEST_NONE = 0x00, + DEST_FPGA = 0x01, + DEST_EEPROM = 0x02, +}; + +#define EXTRAINFO_SIZE 24 + +#endif /* MPPTALK_DEFS_H */ diff --git a/xpp/oct612x/Makefile b/xpp/oct612x/Makefile new file mode 100644 index 0000000..e3e32e5 --- /dev/null +++ b/xpp/oct612x/Makefile @@ -0,0 +1,38 @@ +CFLAGS=-V3.4 -ffunction-sections -I/lib/modules/$(shell uname -r)/build/include -Iinclude -Ioctdeviceapi -Ioctdeviceapi/oct6100api -DGFP_ATOMIC=0 -Dkmalloc=calloc -Dkfree=free +LDFLAGS=-V3.4 -Wl,-Map -Wl,test.map -Wl,--gc-sections + +APIDIR=octdeviceapi/oct6100api/oct6100_api + +OCTASIC_OBJS=$(APIDIR)/oct6100_adpcm_chan.o \ + $(APIDIR)/oct6100_channel.o \ + $(APIDIR)/oct6100_chip_open.o \ + $(APIDIR)/oct6100_chip_stats.o \ + $(APIDIR)/oct6100_conf_bridge.o \ + $(APIDIR)/oct6100_debug.o \ + $(APIDIR)/oct6100_events.o \ + $(APIDIR)/oct6100_interrupts.o \ + $(APIDIR)/oct6100_memory.o \ + $(APIDIR)/oct6100_miscellaneous.o \ + $(APIDIR)/oct6100_mixer.o \ + $(APIDIR)/oct6100_phasing_tsst.o \ + $(APIDIR)/oct6100_playout_buf.o \ + $(APIDIR)/oct6100_remote_debug.o \ + $(APIDIR)/oct6100_tlv.o \ + $(APIDIR)/oct6100_tone_detection.o \ + $(APIDIR)/oct6100_tsi_cnct.o \ + $(APIDIR)/oct6100_tsst.o \ + $(APIDIR)/oct6100_user.o \ + apilib/bt/octapi_bt0.o \ + apilib/largmath/octapi_largmath.o \ + apilib/llman/octapi_llman.o + + +all: test + +test.o: test.c + +test: test.o $(OCTASIC_OBJS) + +clean: + rm -rf test test.o + rm -rf $(OCTASIC_OBJS) diff --git a/xpp/oct612x/apilib/bt/octapi_bt0.c b/xpp/oct612x/apilib/bt/octapi_bt0.c new file mode 100644 index 0000000..f9af44a --- /dev/null +++ b/xpp/oct612x/apilib/bt/octapi_bt0.c @@ -0,0 +1,1217 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_bt0.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Library used to manage a binary tree of variable max size. Library is + made to use one block of contiguous memory to manage the tree. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 18 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#include "apilib/octapi_bt0.h" +#include "octapi_bt0_private.h" + + + +#if !SKIP_OctApiBt0GetSize +UINT32 OctApiBt0GetSize(UINT32 number_of_items,UINT32 key_size, UINT32 data_size, UINT32 * b_size) +{ + if ((key_size % 4) != 0) return(OCTAPI_BT0_KEY_SIZE_NOT_MUTLIPLE_OF_UINT32); + if ((data_size % 4) != 0) return(OCTAPI_BT0_DATA_SIZE_NOT_MUTLIPLE_OF_UINT32); + + *b_size = 0; + *b_size += sizeof(OCTAPI_BT0); + *b_size += sizeof(OCTAPI_BT0_NODE) * number_of_items; + *b_size += key_size * number_of_items; + *b_size += data_size * number_of_items; + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiBt0Init +UINT32 OctApiBt0Init(void ** b,UINT32 number_of_items,UINT32 key_size, UINT32 data_size) +{ + UINT32 i; + OCTAPI_BT0 * bb; + + /* Check input parameters.*/ + if ((key_size % 4) != 0) return(OCTAPI_BT0_KEY_SIZE_NOT_MUTLIPLE_OF_UINT32); + if ((data_size % 4) != 0) return(OCTAPI_BT0_DATA_SIZE_NOT_MUTLIPLE_OF_UINT32); + + /* If b is not already allocated.*/ + if (*b == NULL) return(OCTAPI_BT0_MALLOC_FAILED); + + bb = (OCTAPI_BT0 *)(*b); + + /* Initialize the tree to an empty one!*/ + bb->root_link.node_number = 0xFFFFFFFF; + bb->root_link.depth = 0; + + /* Initialize tree parameters.*/ + bb->number_of_items = number_of_items; + bb->key_size = key_size / 4; + bb->data_size = data_size / 4; + + /* Initialize the next free node pointer.*/ + if (number_of_items != 0) + bb->next_free_node = 0; + else + bb->next_free_node = 0xFFFFFFFF; + + /* Setup the arrays.*/ + OctApiBt0CorrectPointers(bb); + + /* Initialize the Nodes to unused!*/ + for(i=0;inode[i].next_free_node = i + 1; + } + + /* Last empty node points to invalid node.*/ + bb->node[number_of_items-1].next_free_node = 0xFFFFFFFF; + + bb->invalid_value = 0xFFFFFFFF; + bb->no_smaller_key = OCTAPI_BT0_NO_SMALLER_KEY; + + return(GENERIC_OK); +} +#endif + + +#if !SKIP_OctApiBt0CorrectPointers +void OctApiBt0CorrectPointers(OCTAPI_BT0 * bb) +{ + bb->node = (OCTAPI_BT0_NODE *)(((BYTE *)bb) + sizeof(OCTAPI_BT0)); + bb->key = (UINT32 *)(((BYTE *)bb->node) + (sizeof(OCTAPI_BT0_NODE) * bb->number_of_items)); + bb->data = (UINT32 *)(((BYTE *)bb->key) + (sizeof(UINT32) * bb->number_of_items * bb->key_size)); +} +#endif + + +#if !SKIP_OctApiBt0AddNode +UINT32 OctApiBt0AddNode(void * b,void * key,void ** data) +{ + OCTAPI_BT0 * bb; + OCTAPI_BT0_NODE * new_node; + UINT32 * lkey; + UINT32 * nkey; + UINT32 i; + UINT32 new_node_number; + UINT32 result; + + /* Load all!*/ + bb = (OCTAPI_BT0 *)(b); + OctApiBt0CorrectPointers(bb); + + /* Check that there is at least one block left.*/ + if (bb->next_free_node == 0xFFFFFFFF) return(OCTAPI_BT0_NO_NODES_AVAILABLE); + + /* Seize the node!*/ + new_node_number = bb->next_free_node; + new_node = &(bb->node[new_node_number]); + bb->next_free_node = new_node->next_free_node; + + /* Register in the key and the data.*/ + lkey = ((UINT32 *)key); + + /* Find the first UINT32 of the key.*/ + nkey = &(bb->key[bb->key_size * new_node_number]); + + /* Copy the key.*/ + for(i=0;ikey_size;i++) + nkey[i] = lkey[i]; + + /* Attempt to place the node. Only a "multiple hit" will cause an error.*/ + result = OctApiBt0AddNode2(bb,&(bb->root_link), lkey, new_node_number); + if (result != GENERIC_OK) + { + /* This attempt failed. Refree the node!*/ + bb->next_free_node = new_node_number; + + /* Return the error code.*/ + return(result); + } + + /* Return the address of the data to the user.*/ + if ( bb->data_size > 0 ) + *data = (void *)(&(bb->data[bb->data_size * new_node_number])); + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiBt0AddNode2 +UINT32 OctApiBt0AddNode2(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link,UINT32 * lkey,UINT32 new_node_number) +{ + UINT32 result; + + if (link->node_number == 0xFFFFFFFF) /* We have an empty node. Here, we shall place the new node.*/ + { + bb->node[new_node_number].l[0].node_number = 0xFFFFFFFF; + bb->node[new_node_number].l[0].depth = 0; + bb->node[new_node_number].l[1].node_number = 0xFFFFFFFF; + bb->node[new_node_number].l[1].depth = 0; + + /* OCTAPI_BT0_LINK to parent!*/ + link->node_number = new_node_number; + link->depth = 1; /* We are a leaf, last OCTAPI_BT0_LINK depth is 1.*/ + + return(GENERIC_OK); + } + else /* Current node is used, check for a match and a direction.*/ + { + OCTAPI_BT0_NODE * this_node; + UINT32 compare; + + /* Get a pointer to this node.*/ + this_node = &(bb->node[link->node_number]); + + /* Compare this node to the lkey.*/ + compare = OctApiBt0KeyCompare(bb,link,lkey); + + if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/ + { + result = OctApiBt0AddNode2(bb,&(this_node->l[0]), lkey, new_node_number); + if (result != GENERIC_OK) return(result); + } + else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/ + { + result = OctApiBt0AddNode2(bb,&(this_node->l[1]), lkey, new_node_number); + if (result != GENERIC_OK) return(result); + } + else + { + return(OCTAPI_BT0_KEY_ALREADY_IN_TREE); + } + + /* Check if this node is unbalanced by 2. If so, rebalance it:*/ + if (this_node->l[0].depth > (this_node->l[1].depth + 1) || + this_node->l[1].depth > (this_node->l[0].depth + 1)) + { + OctApiBt0Rebalance(bb,link); + } + + /* Always update the OCTAPI_BT0_LINK depth before exiting.*/ + OctApiBt0UpdateLinkDepth(bb,link); + + return(GENERIC_OK); + } +} +#endif + + +#if !SKIP_OctApiBt0AddNode3 +UINT32 OctApiBt0AddNode3(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link,UINT32 * lkey,UINT32 *p_new_node_number) +{ + UINT32 result; + + if (link->node_number == 0xFFFFFFFF) /* We have an empty node. Here, we shall place the new node.*/ + { + if ( *p_new_node_number == 0xFFFFFFFF ) + return(OCTAPI_BT0_NO_NODES_AVAILABLE); + + bb->node[*p_new_node_number].l[0].node_number = 0xFFFFFFFF; + bb->node[*p_new_node_number].l[0].depth = 0; + bb->node[*p_new_node_number].l[1].node_number = 0xFFFFFFFF; + bb->node[*p_new_node_number].l[1].depth = 0; + + /* OCTAPI_BT0_LINK to parent!*/ + link->node_number = *p_new_node_number; + link->depth = 1; /* We are a leaf, last OCTAPI_BT0_LINK depth is 1.*/ + + return(GENERIC_OK); + } + else /* Current node is used, check for a match and a direction.*/ + { + OCTAPI_BT0_NODE * this_node; + UINT32 compare; + + /* Get a pointer to this node.*/ + this_node = &(bb->node[link->node_number]); + + /* Compare this node to the lkey.*/ + compare = OctApiBt0KeyCompare(bb,link,lkey); + + if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/ + { + result = OctApiBt0AddNode3(bb,&(this_node->l[0]), lkey, p_new_node_number); + if (result != GENERIC_OK) return(result); + } + else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/ + { + result = OctApiBt0AddNode3(bb,&(this_node->l[1]), lkey, p_new_node_number); + if (result != GENERIC_OK) return(result); + } + else + { + *p_new_node_number = link->node_number; + return(OCTAPI_BT0_KEY_ALREADY_IN_TREE); + } + + /* Check if this node is unbalanced by 2. If so, rebalance it:*/ + if (this_node->l[0].depth > (this_node->l[1].depth + 1) || + this_node->l[1].depth > (this_node->l[0].depth + 1)) + { + OctApiBt0Rebalance(bb,link); + } + + /* Always update the OCTAPI_BT0_LINK depth before exiting.*/ + OctApiBt0UpdateLinkDepth(bb,link); + + return(GENERIC_OK); + } +} +#endif + +/* state +0 -> first call to the function. +1 -> recursive call.*/ +#if !SKIP_OctApiBt0AddNode4 +UINT32 OctApiBt0AddNode4(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link,UINT32 * lkey,UINT32 *p_new_node_number, UINT32 *p_prev_node_number, UINT32 state ) +{ + UINT32 result; + UINT32 *nkey; + UINT32 *okey; + + if (link->node_number == 0xFFFFFFFF) /* We have an empty node. Here, we shall place the new node.*/ + { + bb->node[*p_new_node_number].l[0].node_number = 0xFFFFFFFF; + bb->node[*p_new_node_number].l[0].depth = 0; + bb->node[*p_new_node_number].l[1].node_number = 0xFFFFFFFF; + bb->node[*p_new_node_number].l[1].depth = 0; + + /* OCTAPI_BT0_LINK to parent!*/ + link->node_number = *p_new_node_number; + link->depth = 1; /* We are a leaf, last OCTAPI_BT0_LINK depth is 1.*/ + + if ( state == 0 ) + *p_prev_node_number = 0xFFFFFFFF; + + return(GENERIC_OK); + } + else /* Current node is used, check for a match and a direction.*/ + { + OCTAPI_BT0_NODE * this_node; + UINT32 compare; + + /* Get a pointer to this node.*/ + this_node = &(bb->node[link->node_number]); + + /* Compare this node to the lkey.*/ + compare = OctApiBt0KeyCompare(bb,link,lkey); + + if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/ + { + if ( state == 0 ) + *p_prev_node_number = OCTAPI_BT0_NO_SMALLER_KEY; + + if ( *p_prev_node_number != OCTAPI_BT0_NO_SMALLER_KEY ) + { + /* Check if the key is the smallest one encountered yet.*/ + okey = &(bb->key[bb->key_size * (*p_prev_node_number)]); + nkey = &(bb->key[bb->key_size * link->node_number]); + /* If the node is key smaller then the old small one, change the value.*/ + if ( *nkey > *okey ) + { + if ( *nkey < *lkey ) + *p_prev_node_number = link->node_number; + } + } + + result = OctApiBt0AddNode4(bb,&(this_node->l[0]), lkey, p_new_node_number, p_prev_node_number, 1); + if (result != GENERIC_OK) return(result); + } + else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/ + { + if ( state == 0 ) + *p_prev_node_number = link->node_number; + else + { + if ( *p_prev_node_number == OCTAPI_BT0_NO_SMALLER_KEY ) + *p_prev_node_number = link->node_number; + else + { + /* Check if the key is the smallest one encountered yet.*/ + okey = &(bb->key[bb->key_size * (*p_prev_node_number)]); + nkey = &(bb->key[bb->key_size * link->node_number]); + /* If the node is key smaller then the old small one, change the value.*/ + if ( *nkey > *okey ) + { + if ( *nkey < *lkey ) + *p_prev_node_number = link->node_number; + } + } + } + + result = OctApiBt0AddNode4(bb,&(this_node->l[1]), lkey, p_new_node_number, p_prev_node_number, 1); + if (result != GENERIC_OK) return(result); + } + else + { + *p_new_node_number = link->node_number; + return(OCTAPI_BT0_KEY_ALREADY_IN_TREE); + } + + /* Check if this node is unbalanced by 2. If so, rebalance it:*/ + if (this_node->l[0].depth > (this_node->l[1].depth + 1) || + this_node->l[1].depth > (this_node->l[0].depth + 1)) + { + OctApiBt0Rebalance(bb,link); + } + + /* Always update the OCTAPI_BT0_LINK depth before exiting.*/ + OctApiBt0UpdateLinkDepth(bb,link); + + return(GENERIC_OK); + } +} +#endif + +#if !SKIP_OctApiBt0KeyCompare +UINT32 OctApiBt0KeyCompare(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link, UINT32 * lkey) +{ + UINT32 * nkey; + UINT32 i; + + /* Find the first UINT32 of the key.*/ + nkey = &(bb->key[bb->key_size * link->node_number]); + + for(i=0;ikey_size;i++) + { + if (lkey[i] < nkey[i]) + return(OCTAPI_BT0_LKEY_SMALLER); + else if (lkey[i] > nkey[i]) + return(OCTAPI_BT0_LKEY_LARGER); + } + + return(OCTAPI_BT0_LKEY_EQUAL); +} +#endif + + +#if !SKIP_OctApiBt0UpdateLinkDepth +void OctApiBt0UpdateLinkDepth(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link) +{ + OCTAPI_BT0_NODE * this_node; + + /* Get a pointer to this node.*/ + this_node = &(bb->node[link->node_number]); + + if (this_node->l[0].depth > this_node->l[1].depth) + link->depth = this_node->l[0].depth + 1; + else + link->depth = this_node->l[1].depth + 1; +} +#endif + +#if !SKIP_OctApiBt0Rebalance +void OctApiBt0Rebalance(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * root_link) +{ + if (bb->node[root_link->node_number].l[0].depth > (bb->node[root_link->node_number].l[1].depth + 1)) /* Heavy to the left.*/ + { + /* Check if the right child of the heavy child node is causing a problem.*/ + /* If so, do a left rotate in order to make the left most child the longer one.*/ + { + OCTAPI_BT0_LINK * heavy_link; + heavy_link = &(bb->node[root_link->node_number].l[0]); + + if (bb->node[heavy_link->node_number].l[1].depth > bb->node[heavy_link->node_number].l[0].depth) + { + OctApiBt0ExternalHeavy(bb,heavy_link); + } + } + + /* Ready to do super rotation!*/ + { + OCTAPI_BT0_LINK init_root_link; + OCTAPI_BT0_LINK init_heavy_link; + OCTAPI_BT0_LINK init_leaf_tree[3]; + + /* Save pertinent initial OCTAPI_BT0_LINK information.*/ + init_root_link = *root_link; + init_heavy_link = bb->node[root_link->node_number].l[0]; + init_leaf_tree[2] = bb->node[root_link->node_number].l[1]; + init_leaf_tree[0] = bb->node[bb->node[root_link->node_number].l[0].node_number].l[0]; + init_leaf_tree[1] = bb->node[bb->node[root_link->node_number].l[0].node_number].l[1]; + + /* Restructure the tree.*/ + *root_link = init_heavy_link; + bb->node[init_heavy_link.node_number].l[1] = init_root_link; + bb->node[init_root_link.node_number].l[0] = init_leaf_tree[1]; + + /* Reconstruct the depth of the branches.*/ + OctApiBt0UpdateLinkDepth(bb,&(bb->node[root_link->node_number].l[1])); + OctApiBt0UpdateLinkDepth(bb,root_link); + } + } + else if (bb->node[root_link->node_number].l[1].depth > (bb->node[root_link->node_number].l[0].depth + 1)) /* Heavy to the right.*/ + { + /* Check if the right child of the heavy child node is causing a problem.*/ + /* If so, do a left rotate in order to make the left most child the longer one.*/ + { + OCTAPI_BT0_LINK * heavy_link; + heavy_link = &(bb->node[root_link->node_number].l[1]); + + if (bb->node[heavy_link->node_number].l[0].depth > bb->node[heavy_link->node_number].l[1].depth) + { + OctApiBt0ExternalHeavy(bb,heavy_link); + } + } + + /* Ready to do super rotation!*/ + { + OCTAPI_BT0_LINK init_root_link; + OCTAPI_BT0_LINK init_heavy_link; + OCTAPI_BT0_LINK init_leaf_tree[3]; + + /* Save pertinent initial OCTAPI_BT0_LINK information.*/ + init_root_link = *root_link; + init_heavy_link = bb->node[root_link->node_number].l[1]; + init_leaf_tree[2] = bb->node[root_link->node_number].l[0]; + init_leaf_tree[0] = bb->node[bb->node[root_link->node_number].l[1].node_number].l[1]; + init_leaf_tree[1] = bb->node[bb->node[root_link->node_number].l[1].node_number].l[0]; + + /* Restructure the tree.*/ + *root_link = init_heavy_link; + bb->node[init_heavy_link.node_number].l[0] = init_root_link; + bb->node[init_root_link.node_number].l[1] = init_leaf_tree[1]; + + /* Reconstruct the depth of the branches.*/ + OctApiBt0UpdateLinkDepth(bb,&(bb->node[root_link->node_number].l[0])); + OctApiBt0UpdateLinkDepth(bb,root_link); + } + } +} +#endif + +/* This function does a rotation towards the outside of the tree*/ +/* in order to keep the heavy branches towards the outside.*/ +#if !SKIP_OctApiBt0ExternalHeavy +void OctApiBt0ExternalHeavy(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * root_link) +{ + if (bb->node[root_link->node_number].l[1].depth > bb->node[root_link->node_number].l[0].depth) /* Exterior of tree is towards the left.*/ + { + OCTAPI_BT0_LINK init_root_link; + OCTAPI_BT0_LINK init_heavy_link; + OCTAPI_BT0_LINK init_leaf_tree[3]; + + /* Save pertinent initial OCTAPI_BT0_LINK information.*/ + init_root_link = *root_link; + init_leaf_tree[0] = bb->node[root_link->node_number].l[0]; + init_heavy_link = bb->node[root_link->node_number].l[1]; + init_leaf_tree[1] = bb->node[bb->node[root_link->node_number].l[1].node_number].l[0]; + init_leaf_tree[2] = bb->node[bb->node[root_link->node_number].l[1].node_number].l[1]; + + /* Restructure the tree.*/ + *root_link = init_heavy_link; + bb->node[init_heavy_link.node_number].l[0] = init_root_link; + bb->node[init_root_link.node_number].l[1] = init_leaf_tree[1]; + + /* Reconstruct the depth of the branches.*/ + OctApiBt0UpdateLinkDepth(bb,&(bb->node[root_link->node_number].l[0])); + OctApiBt0UpdateLinkDepth(bb,root_link); + } + else if (bb->node[root_link->node_number].l[0].depth > bb->node[root_link->node_number].l[1].depth) /* Exterior of tree is towards the right.*/ + { + OCTAPI_BT0_LINK init_root_link; + OCTAPI_BT0_LINK init_heavy_link; + OCTAPI_BT0_LINK init_leaf_tree[3]; + + /* Save pertinent initial OCTAPI_BT0_LINK information.*/ + init_root_link = *root_link; + init_leaf_tree[0] = bb->node[root_link->node_number].l[1]; + init_heavy_link = bb->node[root_link->node_number].l[0]; + init_leaf_tree[1] = bb->node[bb->node[root_link->node_number].l[0].node_number].l[1]; + init_leaf_tree[2] = bb->node[bb->node[root_link->node_number].l[0].node_number].l[0]; + + /* Restructure the tree.*/ + *root_link = init_heavy_link; + bb->node[init_heavy_link.node_number].l[1] = init_root_link; + bb->node[init_root_link.node_number].l[0] = init_leaf_tree[1]; + + /* Reconstruct the depth of the branches.*/ + OctApiBt0UpdateLinkDepth(bb,&(bb->node[root_link->node_number].l[1])); + OctApiBt0UpdateLinkDepth(bb,root_link); + } +} +#endif + + +/* State:*/ +/* 0 = seeking node to be removed.*/ +/* 1 = node found, left branch taken.*/ +/* 2 = node found, right branch taken.*/ +#if !SKIP_OctApiBt0RemoveNode2 +UINT32 OctApiBt0RemoveNode2(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link, UINT32 * lkey, OCTAPI_BT0_LINK * link_to_removed_node, UINT32 state, OCTAPI_BT0_LINK * volatile_grandparent_link) +{ + UINT32 result; + OCTAPI_BT0_NODE * this_node; + + /* Get a pointer to this node.*/ + this_node = &(bb->node[link->node_number]); + + if (state == 0) + { + if (link->node_number == 0xFFFFFFFF) /* We have an empty node. The node we were looking for does not exist.*/ + { + return(OCTAPI_BT0_KEY_NOT_IN_TREE); + } + else /* Current node is used, check for a match and a direction.*/ + { + UINT32 compare; + + /* Compare this node to the lkey.*/ + compare = OctApiBt0KeyCompare(bb,link,lkey); + + if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/ + { + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[0]), lkey, link_to_removed_node, 0, NULL); + if (result != GENERIC_OK) return(result); + } + else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/ + { + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[1]), lkey, link_to_removed_node, 0, NULL); + if (result != GENERIC_OK) return(result); + } + else + { + link_to_removed_node = link; + + /* Keep on going down to find a replacement node.*/ + if (bb->node[link->node_number].l[0].node_number == 0xFFFFFFFF && bb->node[link->node_number].l[1].node_number == 0xFFFFFFFF) + { + /* Doe! No tree left! WHAT TO DO? */ + /* Just delete the current node. That's it.*/ + + /* Release the current node (restore free node link-list)*/ + bb->node[link->node_number].next_free_node = bb->next_free_node; + bb->next_free_node = link->node_number; + + link->node_number = 0xFFFFFFFF; + link->depth = 0; + + return(GENERIC_OK); + } + else if (bb->node[link->node_number].l[0].node_number != 0xFFFFFFFF) /* Left node is present. Go left, then permanently right.*/ + { + OCTAPI_BT0_NODE * removed_node_pnt; + removed_node_pnt = &(bb->node[link->node_number]); + + result = OctApiBt0RemoveNode2(bb,&(removed_node_pnt->l[0]), lkey, link_to_removed_node, 1, link); + if (result != GENERIC_OK) return(result); + + /* Caution! Once we are here, the link->node_pnt->l[0] has been modified,*/ + /* but is about to be discarded! Save it quickly!*/ + /* bb->node[link->node_number].l[0] = removed_node_pnt->l[0];*/ + } + else /* Right node is present. Go right, then permanently left.*/ + { + OCTAPI_BT0_NODE * removed_node_pnt; + removed_node_pnt = &(bb->node[link->node_number]); + + result = OctApiBt0RemoveNode2(bb,&(removed_node_pnt->l[1]), lkey, link_to_removed_node, 2, link); + if (result != GENERIC_OK) return(result); + + /* Caution! Once we are here, the link->node_pnt->l[0] has been modified,*/ + /* but is about to be discarded! Save it quickly!*/ + /* bb->node[link->node_number].l[1] = removed_node_pnt->l[1];*/ + } + } + } + } + else + { + /* Left side, Right-most node found! OR*/ + /* Right side, Left-most node found!*/ + if ((state == 1 && bb->node[link->node_number].l[1].node_number == 0xFFFFFFFF) || + (state == 2 && bb->node[link->node_number].l[0].node_number == 0xFFFFFFFF)) + { + OCTAPI_BT0_LINK init_chosen_link; + + /* Release the current node (restore free node link-list)*/ + bb->node[link_to_removed_node->node_number].next_free_node = bb->next_free_node; + bb->next_free_node = link_to_removed_node->node_number; + + /* Save the link to the chosen node, because it is about to be deleted.*/ + init_chosen_link = *link; + + /* Remove this node, and allow the tree to go on:*/ + { + OCTAPI_BT0_LINK init_child_link[2]; + + init_child_link[0] = bb->node[link->node_number].l[0]; + init_child_link[1] = bb->node[link->node_number].l[1]; + + if (state == 1) + *link = init_child_link[0]; + else + *link = init_child_link[1]; + } + + /* Replace the removed node by this node.*/ + { + OCTAPI_BT0_LINK init_removed_child_link[2]; + + init_removed_child_link[0] = bb->node[link_to_removed_node->node_number].l[0]; + init_removed_child_link[1] = bb->node[link_to_removed_node->node_number].l[1]; + + *link_to_removed_node = init_chosen_link; + bb->node[init_chosen_link.node_number].l[0] = init_removed_child_link[0]; + bb->node[init_chosen_link.node_number].l[1] = init_removed_child_link[1]; + } + + return(GENERIC_OK); + } + else + { + /* Keep on going, we have not found the center most node yet!*/ + if (state == 1) + { + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[1]), lkey, link_to_removed_node, state, NULL); + if (result != GENERIC_OK) return(result); + + /* Refresh the link if our link is volatile.*/ + if (volatile_grandparent_link != NULL) + { + link = &(bb->node[volatile_grandparent_link->node_number].l[0]); + } + } + else + { + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[0]), lkey, link_to_removed_node, state, NULL); + if (result != GENERIC_OK) return(result); + + /* Refresh the link if our link is volatile.*/ + if (volatile_grandparent_link != NULL) + { + link = &(bb->node[volatile_grandparent_link->node_number].l[1]); + } + } + } + } + + /* We may have messed up the tree. So patch it!*/ + /* Check if this node is unbalanced by 2. If so, rebalance it:*/ + if (this_node->l[0].depth > (this_node->l[1].depth + 1) || + this_node->l[1].depth > (this_node->l[0].depth + 1)) + { + OctApiBt0Rebalance(bb,link); + } + + /* Always update the OCTAPI_BT0_LINK depth before exiting.*/ + OctApiBt0UpdateLinkDepth(bb,link); + + return(GENERIC_OK); +} +#endif + + +/* State:*/ +/* 0 = seeking node to be removed.*/ +/* 1 = node found, left branch taken.*/ +/* 2 = node found, right branch taken.*/ +#if !SKIP_OctApiBt0RemoveNode3 +UINT32 OctApiBt0RemoveNode3(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link, UINT32 * lkey, OCTAPI_BT0_LINK * link_to_removed_node, UINT32 state, OCTAPI_BT0_LINK * volatile_grandparent_link, UINT32 *p_prev_node_number ) +{ + UINT32 result; + UINT32 *nkey; + UINT32 *okey; + OCTAPI_BT0_NODE * this_node; + + /* Get a pointer to this node.*/ + this_node = &(bb->node[link->node_number]); + + if (state == 0) + { + if (link->node_number == 0xFFFFFFFF) /* We have an empty node. The node we were looking for does not exist.*/ + { + return(OCTAPI_BT0_KEY_NOT_IN_TREE); + } + else /* Current node is used, check for a match and a direction.*/ + { + UINT32 compare; + + /* Compare this node to the lkey.*/ + compare = OctApiBt0KeyCompare(bb,link,lkey); + + if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/ + { + /* Check if the key is the biggest one encountered yet.*/ + okey = &(bb->key[bb->key_size * (*p_prev_node_number)]); + nkey = &(bb->key[bb->key_size * link->node_number]); + /* If the node is key bigger then the old one, change the value.*/ + if ( *nkey > *okey ) + { + if ( *nkey < *lkey ) + *p_prev_node_number = link->node_number; + } + + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[0]), lkey, link_to_removed_node, 0, NULL); + if (result != GENERIC_OK) return(result); + } + else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/ + { + /* Check if the key is the biggest one encountered yet.*/ + okey = &(bb->key[bb->key_size * (*p_prev_node_number)]); + nkey = &(bb->key[bb->key_size * link->node_number]); + /* If the node is key bigger then the old one, change the value.*/ + if ( *nkey > *okey ) + { + if ( *nkey < *lkey ) + *p_prev_node_number = link->node_number; + } + + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[1]), lkey, link_to_removed_node, 0, NULL); + if (result != GENERIC_OK) return(result); + } + else + { + link_to_removed_node = link; + + /* Keep on going down to find a replacement node.*/ + if (bb->node[link->node_number].l[0].node_number == 0xFFFFFFFF && bb->node[link->node_number].l[1].node_number == 0xFFFFFFFF) + { + /* Doe! No tree left! WHAT TO DO? */ + /* Just delete the current node. That's it.*/ + + /* Release the current node (restore free node link-list)*/ + bb->node[link->node_number].next_free_node = bb->next_free_node; + bb->next_free_node = link->node_number; + + link->node_number = 0xFFFFFFFF; + link->depth = 0; + + return(GENERIC_OK); + } + else if (bb->node[link->node_number].l[0].node_number != 0xFFFFFFFF) /* Left node is present. Go left, then permanently right.*/ + { + OCTAPI_BT0_NODE * removed_node_pnt; + removed_node_pnt = &(bb->node[link->node_number]); + + result = OctApiBt0RemoveNode2(bb,&(removed_node_pnt->l[0]), lkey, link_to_removed_node, 1, link); + if (result != GENERIC_OK) return(result); + + /* Caution! Once we are here, the link->node_pnt->l[0] has been modified,*/ + /* but is about to be discarded! Save it quickly!*/ + /* bb->node[link->node_number].l[0] = removed_node_pnt->l[0];*/ + } + else /* Right node is present. Go right, then permanently left.*/ + { + OCTAPI_BT0_NODE * removed_node_pnt; + removed_node_pnt = &(bb->node[link->node_number]); + + result = OctApiBt0RemoveNode2(bb,&(removed_node_pnt->l[1]), lkey, link_to_removed_node, 2, link); + if (result != GENERIC_OK) return(result); + + /* Caution! Once we are here, the link->node_pnt->l[0] has been modified,*/ + /* but is about to be discarded! Save it quickly!*/ + /* bb->node[link->node_number].l[1] = removed_node_pnt->l[1];*/ + } + } + } + } + else + { + /* Check if the key is the biggest one encountered yet.*/ + okey = &(bb->key[bb->key_size * (*p_prev_node_number)]); + nkey = &(bb->key[bb->key_size * link->node_number]); + /* If the node is key bigger then the old one, change the value.*/ + if ( *nkey > *okey ) + { + if ( *nkey < *lkey ) + *p_prev_node_number = link->node_number; + } + + /* Left side, Right-most node found! OR*/ + /* Right side, Left-most node found!*/ + if ((state == 1 && bb->node[link->node_number].l[1].node_number == 0xFFFFFFFF) || + (state == 2 && bb->node[link->node_number].l[0].node_number == 0xFFFFFFFF)) + { + OCTAPI_BT0_LINK init_chosen_link; + + /* Release the current node (restore free node link-list)*/ + bb->node[link_to_removed_node->node_number].next_free_node = bb->next_free_node; + bb->next_free_node = link_to_removed_node->node_number; + + /* Save the link to the chosen node, because it is about to be deleted.*/ + init_chosen_link = *link; + + /* Remove this node, and allow the tree to go on:*/ + { + OCTAPI_BT0_LINK init_child_link[2]; + + init_child_link[0] = bb->node[link->node_number].l[0]; + init_child_link[1] = bb->node[link->node_number].l[1]; + + if (state == 1) + *link = init_child_link[0]; + else + *link = init_child_link[1]; + } + + /* Replace the removed node by this node.*/ + { + OCTAPI_BT0_LINK init_removed_child_link[2]; + + init_removed_child_link[0] = bb->node[link_to_removed_node->node_number].l[0]; + init_removed_child_link[1] = bb->node[link_to_removed_node->node_number].l[1]; + + *link_to_removed_node = init_chosen_link; + bb->node[init_chosen_link.node_number].l[0] = init_removed_child_link[0]; + bb->node[init_chosen_link.node_number].l[1] = init_removed_child_link[1]; + } + + return(GENERIC_OK); + } + else + { + /* Keep on going, we have not found the center most node yet!*/ + if (state == 1) + { + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[1]), lkey, link_to_removed_node, state, NULL); + if (result != GENERIC_OK) return(result); + + /* Refresh the link if our link is volatile.*/ + if (volatile_grandparent_link != NULL) + { + link = &(bb->node[volatile_grandparent_link->node_number].l[0]); + } + } + else + { + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[0]), lkey, link_to_removed_node, state, NULL); + if (result != GENERIC_OK) return(result); + + /* Refresh the link if our link is volatile.*/ + if (volatile_grandparent_link != NULL) + { + link = &(bb->node[volatile_grandparent_link->node_number].l[1]); + } + } + } + } + + /* We may have messed up the tree. So patch it!*/ + /* Check if this node is unbalanced by 2. If so, rebalance it:*/ + if (this_node->l[0].depth > (this_node->l[1].depth + 1) || + this_node->l[1].depth > (this_node->l[0].depth + 1)) + { + OctApiBt0Rebalance(bb,link); + } + + /* Always update the OCTAPI_BT0_LINK depth before exiting.*/ + OctApiBt0UpdateLinkDepth(bb,link); + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiBt0RemoveNode +UINT32 OctApiBt0RemoveNode(void * b,void * key) +{ + OCTAPI_BT0 * bb; + UINT32 result; + UINT32 * lkey; + + /* Load all!*/ + bb = (OCTAPI_BT0 *)(b); + OctApiBt0CorrectPointers(bb); + + /* Register in the key and the data.*/ + lkey = ((UINT32 *)key); + + /* Attempt to remove the node. Only a "no hit" will cause an error.*/ + result = OctApiBt0RemoveNode2(bb,&(bb->root_link), lkey, NULL, 0, NULL); + if (result != GENERIC_OK) return(result); + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiBt0QueryNode2 +UINT32 OctApiBt0QueryNode2(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link,UINT32 * lkey,UINT32 * node_number) +{ + UINT32 result; + + if (link->node_number == 0xFFFFFFFF) /* We have an empty node. The node we were looking for does not exist.*/ + { + return(OCTAPI_BT0_KEY_NOT_IN_TREE); + } + else /* Current node is used, check for a match and a direction.*/ + { + UINT32 compare; + + /* Compare this node to the lkey.*/ + compare = OctApiBt0KeyCompare(bb,link,lkey); + + if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/ + { + result = OctApiBt0QueryNode2(bb,&(bb->node[link->node_number].l[0]), lkey, node_number); + if (result != GENERIC_OK) return(result); + } + else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/ + { + result = OctApiBt0QueryNode2(bb,&(bb->node[link->node_number].l[1]), lkey, node_number); + if (result != GENERIC_OK) return(result); + } + else + { + /* A match!*/ + *node_number = link->node_number; + } + } + + return(GENERIC_OK); +} +#endif + + +#if !SKIP_OctApiBt0QueryNode +UINT32 OctApiBt0QueryNode(void * b,void * key,void ** data) +{ + OCTAPI_BT0 * bb; + UINT32 node_number; + UINT32 result; + UINT32 * lkey; + + /* Load all!*/ + bb = (OCTAPI_BT0 *)(b); + OctApiBt0CorrectPointers(bb); + + /* Register in the key and the data.*/ + lkey = ((UINT32 *)key); + + /* Get the node number.*/ + result = OctApiBt0QueryNode2(bb,&(bb->root_link),lkey,&node_number); + if (result != GENERIC_OK) return(result); + + /* Return the address of the data to the user.*/ + if ( bb->data_size > 0 ) + *data = (void *)(&(bb->data[bb->data_size * node_number])); + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiBt0GetFirstNode +UINT32 OctApiBt0GetFirstNode(void * b,void ** key, void ** data) +{ + OCTAPI_BT0 * bb; + OCTAPI_BT0_NODE * node; + UINT32 node_number; + UINT32 * lkey; + + /* Load all!*/ + bb = (OCTAPI_BT0 *)(b); + OctApiBt0CorrectPointers(bb); + + /* Register in the key and the data.*/ + lkey = ((UINT32 *)key); + + /* Check if there are any keys present in the tree. */ + if (bb->root_link.node_number == 0xFFFFFFFF) return OCTAPI_BT0_NO_NODES_AVAILABLE; + + node_number = bb->root_link.node_number; + node = &bb->node[node_number]; + + /* Make our way down to the left-most node. */ + while (node->l[0].node_number != 0xFFFFFFFF) + { + node_number = node->l[0].node_number; + node = &bb->node[node_number]; + } + + /* Return the address of the data to the user.*/ + if ( bb->key_size > 0 ) + *key = (void *)(&(bb->key[bb->key_size * node_number])); + + if ( bb->data_size > 0 ) + *data = (void *)(&(bb->data[bb->data_size * node_number])); + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiBt0FindOrAddNode +UINT32 OctApiBt0FindOrAddNode(void * b,void * key,void ** data, UINT32 *fnct_result) +{ + OCTAPI_BT0 * bb; + OCTAPI_BT0_NODE * new_node; + UINT32 * lkey; + UINT32 * nkey; + UINT32 i; + UINT32 new_node_number; + UINT32 temp_node_number = 0; + UINT32 result; + UINT32 tree_already_full = FALSE; + + /* Load all!*/ + bb = (OCTAPI_BT0 *)(b); + OctApiBt0CorrectPointers(bb); + + /* Seize the node!*/ + new_node_number = bb->next_free_node; + /* Register in the key and the data.*/ + lkey = ((UINT32 *)key); + + /* Check that there is at least one block left.*/ + if (bb->next_free_node != 0xFFFFFFFF) + { + + temp_node_number = new_node_number; + new_node = &(bb->node[new_node_number]); + bb->next_free_node = new_node->next_free_node; + + /* Find the first UINT32 of the key.*/ + nkey = &(bb->key[bb->key_size * new_node_number]); + + /* Copy the key.*/ + for(i=0;ikey_size;i++) + nkey[i] = lkey[i]; + } + else + tree_already_full = TRUE; /* Signal that the tree was already full when the function was called.*/ + + /* Attempt to place the node. Only a "multiple hit" will cause an error.*/ + result = OctApiBt0AddNode3(bb,&(bb->root_link), lkey, &new_node_number); + switch( result ) + { + case GENERIC_OK: + *fnct_result = OCTAPI0_BT0_NODE_ADDDED; + break; + case OCTAPI_BT0_KEY_ALREADY_IN_TREE: + *fnct_result = OCTAPI0_BT0_NODE_FOUND; + /* This attempt did not add a new node. Refree the node!*/ + if ( tree_already_full == FALSE ) + bb->next_free_node = temp_node_number; + result = GENERIC_OK; + break; + default: + break; + } + + if (result != GENERIC_OK) + { + /* This attempt failed. Refree the node!*/ + if ( tree_already_full == FALSE ) + bb->next_free_node = new_node_number; + + /* Return the error code.*/ + return(result); + } + + /* Return the address of the data to the user.*/ + if ( bb->data_size > 0 ) + *data = (void *)(&(bb->data[bb->data_size * new_node_number])); + + return(GENERIC_OK); +} +#endif + + +#if !SKIP_OctApiBt0AddNodeReportPrevNodeData +UINT32 OctApiBt0AddNodeReportPrevNodeData(void * b,void * key,void ** data, void ** prev_data, PUINT32 fnct_result ) +{ + OCTAPI_BT0 * bb; + OCTAPI_BT0_NODE * new_node; + UINT32 * lkey; + UINT32 * nkey; + UINT32 i; + UINT32 new_node_number; + UINT32 temp_node_number; + UINT32 prev_node_number; + UINT32 result; + + /* Load all!*/ + bb = (OCTAPI_BT0 *)(b); + OctApiBt0CorrectPointers(bb); + + /* Check that there is at least one block left.*/ + if (bb->next_free_node == 0xFFFFFFFF) return(OCTAPI_BT0_NO_NODES_AVAILABLE); + + /* Seize the node!*/ + new_node_number = bb->next_free_node; + temp_node_number = new_node_number; + new_node = &(bb->node[new_node_number]); + bb->next_free_node = new_node->next_free_node; + + /* Set the previous node value */ + prev_node_number = 0xFFFFFFFF; + + /* Register in the key and the data.*/ + lkey = ((UINT32 *)key); + + /* Find the first UINT32 of the key.*/ + nkey = &(bb->key[bb->key_size * new_node_number]); + + /* Copy the key.*/ + for(i=0;ikey_size;i++) + nkey[i] = lkey[i]; + + /* Attempt to place the node. Only a "multiple hit" will cause an error.*/ + result = OctApiBt0AddNode4(bb,&(bb->root_link), lkey, &new_node_number, &prev_node_number, 0); + switch( result ) + { + case GENERIC_OK: + *fnct_result = OCTAPI0_BT0_NODE_ADDDED; + break; + case OCTAPI_BT0_KEY_ALREADY_IN_TREE: + *fnct_result = OCTAPI0_BT0_NODE_FOUND; + /* This attempt did not add a new node. Refree the node!*/ + bb->next_free_node = temp_node_number; + result = GENERIC_OK; + break; + default: + break; + } + + if (result != GENERIC_OK) + { + /* This attempt failed. Refree the node!*/ + bb->next_free_node = new_node_number; + + /* Return the error code.*/ + return(result); + } + + /* Return the address of the data to the user.*/ + if ( bb->data_size > 0 ) + *data = (void *)(&(bb->data[bb->data_size * new_node_number])); + + if ( bb->data_size > 0 ) + { + if ( (prev_node_number != 0xFFFFFFFF) && + (prev_node_number != OCTAPI_BT0_NO_SMALLER_KEY) && + (*fnct_result == OCTAPI0_BT0_NODE_ADDDED)) + *prev_data = ( void* )(&(bb->data[bb->data_size * prev_node_number])); + else if ( prev_node_number == 0xFFFFFFFF ) + *prev_data = ( void* )(&bb->invalid_value); + else if ( prev_node_number == OCTAPI_BT0_NO_SMALLER_KEY ) + *prev_data = ( void* )(&bb->no_smaller_key); + } + + return(GENERIC_OK); +} +#endif + diff --git a/xpp/oct612x/apilib/bt/octapi_bt0_private.h b/xpp/oct612x/apilib/bt/octapi_bt0_private.h new file mode 100644 index 0000000..8c68c3e --- /dev/null +++ b/xpp/oct612x/apilib/bt/octapi_bt0_private.h @@ -0,0 +1,93 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_bt0_private.h + +Copyright (c) 2001 Octasic Inc. All rights reserved. + +Description: + + Library used to manage a binary tree of variable max size. Library is + made to use one block of contiguous memory to manage the tree. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 11 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#ifndef __OCTAPI_BT0_PRIVATE_H__ +#define __OCTAPI_BT0_PRIVATE_H__ + + + +#include "octdef.h" + +#define OCTAPI_BT0_LKEY_LARGER 0x0 +#define OCTAPI_BT0_LKEY_SMALLER 0x1 +#define OCTAPI_BT0_LKEY_EQUAL 0x2 + +typedef struct __OCTAPI_BT0_LINK__ +{ + UINT32 node_number; + UINT32 depth; +} OCTAPI_BT0_LINK; + +typedef struct __OCTAPI_BT0_NODE__ +{ + UINT32 next_free_node; /* Number of the next node in the free node link-list.*/ + OCTAPI_BT0_LINK l[2]; /* 0 = left link; 1 = right link.*/ +} OCTAPI_BT0_NODE; + + +typedef struct __OCTAPI_BT0__ +{ + UINT32 number_of_items; /* Number of items on total that can be allocated in the tree.*/ + UINT32 key_size; /* Size is in UINT32s*/ + UINT32 data_size; /* Size is in UINT32s*/ + + /* Empty node linked-list:*/ + UINT32 next_free_node; /* 0xFFFFFFFF means that no nodes are free.*/ + + /* Tree as such:*/ + OCTAPI_BT0_NODE * node; /* Array of nodes (number_of_items in size).*/ + + /* Tree root:*/ + OCTAPI_BT0_LINK root_link; + + /* Associated key structure*/ + UINT32 * key; /* Array of keys associated to NODEs.*/ + + /* Associated data structure.*/ + UINT32 * data; /* Array of data associated to NODEs.*/ + + UINT32 invalid_value; + UINT32 no_smaller_key; + +} OCTAPI_BT0; + +void OctApiBt0CorrectPointers( OCTAPI_BT0 * bb ); +UINT32 OctApiBt0AddNode2( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * link, UINT32 * lkey, UINT32 new_node_number ); +UINT32 OctApiBt0AddNode3( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * link, UINT32 * lkey, UINT32 *p_new_node_number ); +UINT32 OctApiBt0AddNode4(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link,UINT32 * lkey,UINT32 *p_new_node_number, UINT32 *p_prev_node_number, UINT32 state ); +UINT32 OctApiBt0KeyCompare( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * link, UINT32 * lkey ); +void OctApiBt0UpdateLinkDepth( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * link ); +void OctApiBt0Rebalance( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * root_link ); +void OctApiBt0ExternalHeavy( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * root_link ); +UINT32 OctApiBt0RemoveNode2( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * link, UINT32 * lkey, OCTAPI_BT0_LINK * link_to_removed_node, UINT32 state, OCTAPI_BT0_LINK * volatile_grandparent_link ); + + + +#endif /*__OCTAPI_BT0_PRIVATE_H__*/ diff --git a/xpp/oct612x/apilib/largmath/octapi_largmath.c b/xpp/oct612x/apilib/largmath/octapi_largmath.c new file mode 100644 index 0000000..75153b8 --- /dev/null +++ b/xpp/oct612x/apilib/largmath/octapi_largmath.c @@ -0,0 +1,628 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_largmath.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Library used to perform arithmetic on integer values of an integer multiple + of 32-bits. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 10 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#include "apilib/octapi_largmath.h" + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLmAdd. +| +| Description: This function adds 2 numbers, a and b. Number a is +| (alen + 1) * 32 bits long; b is (blen + 1) * 32 bits long. The +| result is (zlen + 1) * 32 bits long. It the function succeeds it returns +| GENERIC_OK, else GENERIC_ERROR. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *a UINT32 The array containing the first number. +| alen USHORT The length of array a, minus 1 (0 - 99). +| *b UINT32 The array containing the second number. +| blen USHORT The length of array b, minus 1 (0 - 99). +| *z UINT32 The array containing the resulting number. +| zlen USHORT The length of array z, minus 1 (0 - 99). +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmAdd +UINT32 OctApiLmAdd(UINT32 * a,USHORT alen,UINT32 * b,USHORT blen,UINT32 * z, USHORT zlen) +{ + USHORT i; + UINT32 temp; + UINT32 carry=0; + UINT32 aprim; + UINT32 bprim; + + /* Check for array lengths.*/ + if (alen > zlen || blen > zlen) return(OCTAPI_LM_ARRAY_SIZE_MISMATCH); + + for(i=0;i<=zlen;i++) + { + if (i <= alen) aprim = *(a+i); else aprim = 0; + if (i <= blen) bprim = *(b+i); else bprim = 0; + temp = aprim + bprim + carry; + + /* Calculate carry for next time.*/ + if (carry == 0) + if (temp < aprim) carry = 1; else carry = 0; + else + if (temp <= aprim) carry = 1; else carry = 0; + + /* Write new value.*/ + *(z+i) = temp; + } + + /* Check for overflow.*/ + if (carry == 1) return(OCTAPI_LM_OVERFLOW); + + /* All is well.*/ + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLmSubtract. +| +| Description: This function subtracts 2 numbers, a and b. Number a is +| (alen + 1) * 32 bits long; b is (blen + 1) * 32 bits long. The result +| is (zlen + 1) * 32 bits long. It the function succeeds it returns +| GENERIC_OK, else GENERIC_ERROR. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *a UINT32 The array containing the first number. +| alen USHORT The length of array a, minus 1 (0 - 99). +| *bneg UINT32 The array containing the second number. +| blen USHORT The length of array b, minus 1 (0 - 99). +| *z UINT32 The array containing the resulting number. +| zlen USHORT The length of array z, minus 1 (0 - 99). +| *neg USHORT Indicates if the result is negative +| (TRUE/FALSE). +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmSubtract +UINT32 OctApiLmSubtract(UINT32 * a,USHORT alen,UINT32 * bneg,USHORT blen,UINT32 * z,USHORT zlen,USHORT * neg) +{ + USHORT i; + UINT32 temp; + UINT32 carry=1; + UINT32 aprim; + UINT32 bprim; + + /* Check for array lengths.*/ + if (alen > zlen || blen > zlen) return(OCTAPI_LM_ARRAY_SIZE_MISMATCH); + + for(i=0;i<=zlen;i++) + { + if (i <= alen) aprim = *(a+i); else aprim = 0; + if (i <= blen) bprim = ~(*(bneg+i)); else bprim = 0xFFFFFFFF; + temp = aprim + bprim + carry; + + /* Calculate carry for next time.*/ + if (carry == 0) + if (temp < aprim) carry = 1; else carry = 0; + else + if (temp <= aprim) carry = 1; else carry = 0; + + /* Write new value.*/ + *(z+i) = temp; + } + + /* Check for overflow, which means negative number!*/ + if (carry == 0) + { + /* Number is not of right neg. Invert and add one to correct neg.*/ + for(i=0;i<=zlen;i++) + *(z+i) = ~(*(z+i)); + + temp = 1; + OctApiLmAdd(&temp,0,z,zlen,z,zlen); + + *neg = TRUE; + return(GENERIC_OK); + } + + /* Result is positive.*/ + *neg = FALSE; + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLmCompare. +| +| Description: This function compares two numbers (arrays) of equal lengths. +| Number a is (alen + 1) * 32 bits long; b is (blen + 1) * 32 bits long. The result +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *a UINT32 The array containing the first number. +| alen USHORT The length of array a, minus 1 (0 - 99). +| *b UINT32 The array containing the second number. +| blen USHORT The length of array b, minus 1 (0 - 99). +| *neg USHORT Result of compare. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmCompare +UINT32 OctApiLmCompare(UINT32 * a,USHORT alen,UINT32 * bneg,USHORT blen,USHORT * neg) +{ + USHORT i; + UINT32 temp; + UINT32 carry=1; + UINT32 aprim; + UINT32 bprim; + UINT32 zlen; + + /* Set zlen to alen or blen (which ever is longer)*/ + if (alen < blen) + zlen = blen; + else + zlen = alen; + + for(i=0;i<=zlen;i++) + { + if (i <= alen) aprim = *(a+i); else aprim = 0; + if (i <= blen) bprim = ~(*(bneg+i)); else bprim = 0xFFFFFFFF; + temp = aprim + bprim + carry; + + /* Calculate carry for next time.*/ + if (carry == 0) + if (temp < aprim) carry = 1; else carry = 0; + else + if (temp <= aprim) carry = 1; else carry = 0; + } + + /* Check for overflow, which means negative number!*/ + if (carry == 0) + { + *neg = TRUE; + return(GENERIC_OK); + } + + /* Result is positive.*/ + *neg = FALSE; + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLmSubtract. +| +| Description: This function multiplies 2 numbers, a and b. Number a and +| b are both (ablen + 1) * 32 bits long. The result is twice as +| long. If the functions succeeds if returns GENERIC_OK, +| else GENERIC_ERROR. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *a UINT32 The array containing the first number. +| *b UINT32 The array containing the second number. +| ablen USHORT The length of arrays a and b, minus 1 (0 - 99). +| *z UINT32 The array containing the resulting number. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmMultiply +UINT32 OctApiLmMultiply(UINT32 * a,UINT32 * b,USHORT ablen,UINT32 * z) +{ + USHORT i,j,k; + USHORT nos; + UINT32 lownum; + UINT32 highnum; + USHORT longnumi; + USHORT longnumj; + USHORT indentw,indentl; + + + /* Caculate number of shorts in a and b.*/ + nos = (USHORT)((ablen+1) * 2); + + /* Clear answer word.*/ + for(i=0;i OCTAPI_LM_MAX_OPTIMIZE_MUL) + optimizea = FALSE; + if(*b > OCTAPI_LM_MAX_OPTIMIZE_MUL) + optimizeb = FALSE; + + if(optimizea == TRUE) + { + for(l = 0; l < *a; l++) + OctApiLmAdd(z, (USHORT)(nos-1), b, ablen, z, (USHORT)(nos-1)); + return(GENERIC_OK); + } + + if(optimizeb == TRUE) + { + for(l = 0; l < *b; l++) + OctApiLmAdd(z, (USHORT)(nos-1), a, ablen, z, (USHORT)(nos-1)); + return(GENERIC_OK); + } + } + + for(i=0;i>16; /* Odd word. Upper part of long.*/ + + for(j=0;j>16; /* Odd word. Upper part of long.*/ + + /* Find the word indent of the answer. 0 = no indent. 1 = one word indent.*/ + indentw = (USHORT)( j+i ); + indentl = (USHORT)( indentw / 2 ); + + /* Multiply both numbers.*/ + product = highnum * lownum; + + /* After multiplying both numbers, add result to end result.*/ + if ((indentw % 2) == 0) /* Even word boundary, addition in one shot!*/ + { + UINT32 carry=0; + UINT32 temp; + UINT32 addme; + + for(k=indentl;k>16; + else addme = 0; + + temp = *(z+k) + addme + carry; + + /* Calculate carry for next time.*/ + if (carry == 0) + if (temp < addme) carry = 1; else carry = 0; + else + if (temp <= addme) carry = 1; else carry = 0; + + /* Set value.*/ + *(z+k) = temp; + } + + /* Carry should always be 0.*/ + if (carry == 1) return(GENERIC_ERROR); + } + } + } + + return(GENERIC_OK); +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLmDivide. +| +| Description: This function divides the number n by the number d. The +| quotient is placed in q and the remainder in r. The arrays +| n, d, q and r are all of the same length, namely (ndqrlen + 1). +| If the functions succeeds if returns GENERIC_OK, else +| GENERIC_ERROR. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *a UINT32 The array containing the first number. +| *b UINT32 The array containing the second number. +| ablen USHORT The length of arrays a and b, minus 1 (0 - 99). +| *z UINT32 The array containing the resulting number. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmDivide +UINT32 OctApiLmDivide(UINT32 * n,UINT32 * d,UINT32 * q,UINT32 * r,USHORT ndqrlen) +{ + /* Proceedure for division:*/ + /* r = n*/ + /* q = 0*/ + /* shift = initial_denominator_shift (for upper '1's to be in same bit position).*/ + /* d <<= shift;*/ + /* Start loop:*/ + /* compare r and d*/ + /* if r > d then*/ + /* r -= d;*/ + /* write a '1' to bit "shift" of array q.*/ + /* end if;*/ + /* if shift == 0 then*/ + /* return;*/ + /* else*/ + /* shift--;*/ + /* d>>=1;*/ + /* goto "Start loop:"*/ + /* end if;*/ + + UINT32 i; + UINT32 result; + USHORT shift,n_msb,d_msb; + USHORT neg; + USHORT ConditionFlag = TRUE; + + /* r = n*/ + for(i=0;i<=ndqrlen;i++) + *(r+i) = *(n+i); + + /* q = 0*/ + for(i=0;i<=ndqrlen;i++) + *(q+i) = 0; + + /* shift = initial_denominator_shift (for upper '1's to be in same bit position).*/ + result = OctApiLmGetMsb(d,ndqrlen,&d_msb); + if (result != GENERIC_OK) return(result); + + result = OctApiLmGetMsb(n,ndqrlen,&n_msb); + if (result != GENERIC_OK) return(result); + + if (d_msb == 0xFFFF) /* Division by 0.*/ + return(OCTAPI_LM_DIVISION_BY_ZERO); + + if (n_msb == 0xFFFF) /* 0/n, returns 0 R 0.*/ + return(GENERIC_OK); + + if (n_msb < d_msb) /* x/y, where x is smaller than y, returns 0 R x.*/ + return(GENERIC_OK); + + shift = (USHORT)( n_msb - d_msb ); + + /* Shift d to match n highest bit position.*/ + result = OctApiLmShiftn(d,ndqrlen,TRUE,shift); + if (result != GENERIC_OK) return(result); + + /* Start loop:*/ + while( ConditionFlag == TRUE ) + { + /* compare r and d*/ + result = OctApiLmCompare(r,ndqrlen,d,ndqrlen,&neg); + if (result != GENERIC_OK) return(result); + + if (neg == FALSE) /* Subtraction can be done(do it).*/ + { + /* r -= d;*/ + result = OctApiLmSubtract(r,ndqrlen,d,ndqrlen,r,ndqrlen,&neg); + if (result != GENERIC_OK) return(result); + + /* write a '1' to bit "shift" of array q.*/ + *(q+(shift/32)) |= (UINT32)0x1 << (shift%32); + } + + /* if shift == 0 then*/ + /* return;*/ + if (shift == 0) return(GENERIC_OK); + + /* shift--;*/ + /* d>>=1;*/ + /* goto "Start loop:"*/ + shift--; + OctApiLmShiftRight1(d,ndqrlen); + } + + return(GENERIC_OK); +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: octapi_lm_shifright1. +| +| Description: The function is for internal use only. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| N/A. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmShiftRight1 +UINT32 OctApiLmShiftRight1(UINT32 * a,USHORT alen) +{ + UINT32 i; + + /* Start with lower long and move up by one long each time,*/ + /* shifting each long to the right by one bit. The upper bit*/ + /* of the next long will have to be concatenated each time a*/ + /* loop is executed. For the last long, leave the highest bit*/ + /* intact.*/ + for(i=0;i>=1; /* Shift long by one to the right.*/ + *(a+i)|=*(a+i+1)<<31; + } + *(a+alen)>>=1; /* Shift last long, leaving it's highest bit at 0.*/ + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLmShiftn. +| +| Description: The function is for internal use only. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| N/A. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmShiftn +UINT32 OctApiLmShiftn(UINT32 * a,USHORT alen,USHORT shiftleft,USHORT shiftn) +{ + UINT32 i; + USHORT long_offset; + USHORT bit_offset; + + long_offset = (USHORT)( shiftn / 32 ); + bit_offset = (USHORT)( shiftn % 32 ); + + if (shiftleft == TRUE) /* Shift left.*/ + { + for(i=alen;i<=alen;i--) + { + /* Fill upper bits of long.*/ + if (i >= long_offset) + *(a+i) = *(a+i-long_offset) << bit_offset; + else + *(a+i) = 0; + + /* Fill lower bits of long.*/ + if (i > long_offset && bit_offset != 0) + *(a+i) |= *(a+i-long_offset-1) >> (32-bit_offset); + } + } + else /* Shift right.*/ + { + for(i=0;i<=alen;i++) + { + /* Fill lower bits of long.*/ + if ((alen-i) >= long_offset) + *(a+i) = *(a+i+long_offset) >> bit_offset; + else + *(a+i) = 0; + + /* Fill upper bits of long.*/ + if ((alen-i) > long_offset && bit_offset != 0) + *(a+i) |= *(a+i+long_offset+1) << (32-bit_offset); + + } + } + + return(GENERIC_OK); +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLmGetMsb. +| +| Description: The function is for internal use only. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| N/A. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmGetMsb +UINT32 OctApiLmGetMsb(UINT32 * a,USHORT alen,USHORT * msb_pos) +{ + UINT32 i,j; + UINT32 x; + + for(i=alen;i<=alen;i--) + { + if (*(a+i) == 0) continue; + + x = *(a+i); + for(j=31;j<=31;j--) + { + /* Test for bit being '1'.*/ + if ((x & 0x80000000) != 0) + { + *msb_pos=(USHORT)(j+(32*i)); + return(GENERIC_OK); + } + + /* Shift bit one bit position, and try again.*/ + x<<=1; + } + } + + /* MSB not found.*/ + *msb_pos = 0xFFFF; + + return(GENERIC_OK); +} +#endif diff --git a/xpp/oct612x/apilib/llman/octapi_llman.c b/xpp/oct612x/apilib/llman/octapi_llman.c new file mode 100644 index 0000000..9926d20 --- /dev/null +++ b/xpp/oct612x/apilib/llman/octapi_llman.c @@ -0,0 +1,2787 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_llman.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Library used to manage allocation tables and linked lists. The library is + made such that only a block of contiguous memory is needed for the + management of the linked list/allocation table. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 22 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#include "octapi_llman_private.h" +#include "apilib/octapi_llman.h" +#include "apilib/octapi_largmath.h" + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctapiLlmAllocGetSize. +| +| Description: This function determines the amount of memory needed to +| manage the allocation of a fixed amount of resources. +| The memory is measured in bytes. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| number_of_items UINT32 The number of resources to be allocated. +| *l_size UINT32 UINT32 The amount of memory needed, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctapiLlmAllocGetSize +UINT32 OctapiLlmAllocGetSize(UINT32 number_of_items,UINT32 * l_size) +{ + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + + *l_size = (sizeof(LLM_ALLOC)) + (number_of_items * sizeof(UINT32)); + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctapiLlmAllocInit. +| +| Description: This function intializes the LLM_ALLOC structure. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| **l void The memory used by the LLM_ALLOC structure. +| number_of_items UINT32 The number of resources to be allocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctapiLlmAllocInit +UINT32 OctapiLlmAllocInit(void ** l,UINT32 number_of_items) +{ + LLM_ALLOC* ls; + UINT32 i; + + /* Check the number of items required.*/ + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + + /* If no memory has been allocated yet:*/ + if (*l == NULL) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Build the structure before starting.*/ + ls = (LLM_ALLOC *)(*l); + ls->linked_list = (UINT32 *)((BYTE *)ls + sizeof(LLM_ALLOC)); + + ls->number_of_items = number_of_items; + + /* Linked list links all structures in ascending order.*/ + for(i=0;ilinked_list[i] = i+1; + } + + ls->linked_list[number_of_items - 1] = 0xFFFFFFFF; /* Invalid link.*/ + + /* Next avail is 0.*/ + ls->next_avail_num = 0; + + /* Number of allocated items is null.*/ + ls->allocated_items = 0; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctapiLlmAllocInfo. +| +| Description: This function returns the number of free and allocated +| block in the LLMAN list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| *allocated_items UINT32 Number of allocated items. +| *available_items UINT32 Number of available items. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctapiLlmAllocInfo +UINT32 OctapiLlmAllocInfo(void * l,UINT32 * allocated_items,UINT32 * available_items) +{ + LLM_ALLOC* ls; + + /* Build the structure before starting.*/ + ls = (LLM_ALLOC *)l; + ls->linked_list = (UINT32 *)((BYTE *)ls + sizeof(LLM_ALLOC)); + + *allocated_items = ls->allocated_items; + *available_items = ls->number_of_items - ls->allocated_items; + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctapiLlmAllocInfo. +| +| Description: This function allocates the resource indicated by blocknum. +| If the resource can be allocated then GENERIC_OK is returned. +| Else an error. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| *block_num UINT32 The resource to be allocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctapiLlmAllocAlloc +UINT32 OctapiLlmAllocAlloc(void * l,UINT32 * blocknum) +{ + LLM_ALLOC* ls; + UINT32 allocated_block; + UINT32* node; + + /* Build the structure before starting.*/ + ls = (LLM_ALLOC *)l; + ls->linked_list = (UINT32 *)((BYTE *)ls + sizeof(LLM_ALLOC)); + + /* Get next available block number.*/ + allocated_block = ls->next_avail_num; + + /* Check if block is invalid.*/ + if (allocated_block == 0xFFFFFFFF) + { + /* Make blocknum NULL.*/ + *blocknum = 0xFFFFFFFF; + + return(OCTAPI_LLM_NO_STRUCTURES_LEFT); + } + + node = &ls->linked_list[allocated_block]; + + /* Copy next block number.*/ + ls->next_avail_num = *node; + + /* Tag as used the current block number.*/ + *node = 0xFFFFFFFE; + + /* Return proper block number.*/ + *blocknum = allocated_block; + + /* Update block usage number.*/ + ls->allocated_items++; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctapiLlmAllocDealloc. +| +| Description: This function deallocates the resource indicated by blocknum. +| If the resource is not already allocated an error is returned. +| Else GENERIC_OK is returned. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| block_num UINT32 The resource to be deallocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctapiLlmAllocDealloc +UINT32 OctapiLlmAllocDealloc(void * l,UINT32 blocknum) +{ + LLM_ALLOC* ls; + UINT32* node; + + /* Build the structure before starting.*/ + ls = (LLM_ALLOC *)l; + ls->linked_list = (UINT32 *)((BYTE *)ls + sizeof(LLM_ALLOC)); + + /* Check for null item pointer.*/ + if (blocknum == 0xFFFFFFFF) return(GENERIC_OK); + + /* Check if blocknum is within specified item range.*/ + if (blocknum >= ls->number_of_items) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + + node = &ls->linked_list[blocknum]; + + /* Check if block is really used as of now.*/ + if (*node != 0xFFFFFFFE) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Add link to list.*/ + *node = ls->next_avail_num; + + /* Point to returned block.*/ + ls->next_avail_num = blocknum; + + /* Update block usage number.*/ + ls->allocated_items--; + + return(GENERIC_OK); +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmAllocGetSize. +| +| Description: This function determines the amount of memory needed to +| manage the allocation of a fixed amount of resources. +| The memory is measured in bytes. +| +| This version is a time manage version of llman. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| number_of_items UINT32 The number of resources to be allocated. +| *l_size UINT32 UINT32 The amount of memory needed, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiTllmAllocGetSize +UINT32 OctApiTllmAllocGetSize(UINT32 number_of_items,UINT32 * l_size) +{ + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + + *l_size = (sizeof(TLLM_ALLOC)) + (number_of_items * sizeof(TLLM_ALLOC_NODE)); + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmAllocInit. +| +| Description: This function intializes the TLLM_ALLOC structure. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| **l void The memory used by the LLM_ALLOC structure. +| number_of_items UINT32 The number of resources to be allocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiTllmAllocInit +UINT32 OctApiTllmAllocInit(void ** l,UINT32 number_of_items) +{ + TLLM_ALLOC* ls; + UINT32 i; + + /* Check the number of items required.*/ + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + + /* If no memory has been allocated yet.*/ + if (*l == NULL) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Build the structure before starting.*/ + ls = (TLLM_ALLOC *)(*l); + ls->linked_list = (TLLM_ALLOC_NODE *)((BYTE *)ls + sizeof(TLLM_ALLOC)); + + ls->number_of_items = number_of_items; + + /* Linked list links all structures in ascending order.*/ + for(i=0;ilinked_list[i].value = i+1; + } + + ls->linked_list[number_of_items - 1].value = 0xFFFFFFFF; /* Invalid link.*/ + + /* Next avail is 0.*/ + ls->next_avail_num = 0; + + /* Number of allocated items is null.*/ + ls->allocated_items = 0; + + /* Set the number of timeout entry.*/ + ls->number_of_timeout = 0; + + /* Next timeout is 0.*/ + ls->next_timeout_num = 0xFFFFFFFF; + ls->last_timeout_num = 0xFFFFFFFF; + + /* Set the known time to 0.*/ + ls->last_known_time[ 0 ] = 0; + ls->last_known_time[ 1 ] = 0; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmAllocInfo. +| +| Description: This function returns the number of free and allocated +| block in the TLLMAN list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| *allocated_items UINT32 Number of allocated items. +| *available_items UINT32 Number of available items. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiTllmAllocInfo +UINT32 OctApiTllmAllocInfo(void * l,UINT32 * allocated_items,UINT32 * available_items) +{ + TLLM_ALLOC* ls; + + /* Build the structure before starting.*/ + ls = (TLLM_ALLOC *)l; + *allocated_items = ls->allocated_items; + *available_items = ls->number_of_items - ls->allocated_items; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmAllocAlloc. +| +| Description: This function allocates the resource indicated by blocknum. +| If the resource can be allocated then GENERIC_OK is returned. +| Else an error. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| *block_num UINT32 The resource to be allocated. +| *current_time UINT32 +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiTllmAllocAlloc +UINT32 OctApiTllmAllocAlloc(void * l,UINT32 * blocknum, UINT32 *current_time) +{ + TLLM_ALLOC* ls; + UINT32 allocated_block; + TLLM_ALLOC_NODE* node; + + /* Build the structure before starting.*/ + ls = (TLLM_ALLOC *)l; + ls->linked_list = (TLLM_ALLOC_NODE *)((BYTE *)ls + sizeof(TLLM_ALLOC)); + + if ( ls->allocated_items == ls->number_of_items && + ls->next_timeout_num != 0xFFFFFFFF ) + { + UINT32 l_ulResult; + l_ulResult = OctApiTllmCheckTimeoutList( ls, current_time ); + if ( l_ulResult != GENERIC_OK ) + return l_ulResult; + } + + /* Get next available block number.*/ + allocated_block = ls->next_avail_num; + + /* Check if block is invalid.*/ + if (allocated_block == 0xFFFFFFFF) + { + /* Make blocknum NULL.*/ + *blocknum = 0xFFFFFFFF; + + return(OCTAPI_LLM_NO_STRUCTURES_LEFT); + } + + node = &ls->linked_list[allocated_block]; + + /* Copy next block number.*/ + ls->next_avail_num = node->value; + + /* Tag as used the current block number.*/ + node->value = 0xFFFFFFFE; + + /* Return proper block number.*/ + *blocknum = allocated_block; + + /* Update block usage number.*/ + ls->allocated_items++; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmAllocDealloc. +| +| Description: This function deallocates the resource indicated by blocknum. +| If the resource is not already allocated an error is returned. +| Else GENERIC_OK is returned. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| block_num UINT32 The resource to be deallocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiTllmAllocDealloc +UINT32 OctApiTllmAllocDealloc(void * l,UINT32 blocknum, UINT32 timeout_value, UINT32 current_time[2]) +{ + TLLM_ALLOC* ls; + TLLM_ALLOC_NODE* node; + UINT32 l_ulResult; + + /* Build the structure before starting.*/ + ls = (TLLM_ALLOC *)l; + ls->linked_list = (TLLM_ALLOC_NODE *)((BYTE *)ls + sizeof(TLLM_ALLOC)); + + /* Check for null item pointer.*/ + if (blocknum == 0xFFFFFFFF) return(GENERIC_OK); + + /* Check if blocknum is within specified item range.*/ + if (blocknum >= ls->number_of_items) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + + if ( ls->next_timeout_num != 0xFFFFFFFF ) + { + l_ulResult = OctApiTllmCheckTimeoutList( ls, current_time ); + if ( l_ulResult != GENERIC_OK ) + return l_ulResult; + } + + node = &ls->linked_list[blocknum]; + + /* Check if block is really used as of now.*/ + if (node->value != 0xFFFFFFFE) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Add link to timeout list.*/ + if ( ls->last_timeout_num != 0xFFFFFFFF ) + { + TLLM_ALLOC_NODE* last_node; + + /* insert the node at the end of the list.*/ + node->value = 0xFFFFFFFF; + last_node = &ls->linked_list[ ls->last_timeout_num ]; + last_node->value = blocknum; + } + else + { + /* The node is alone in the list.*/ + node->value = 0xFFFFFFFF; + ls->next_timeout_num = blocknum; + } + + ls->last_timeout_num = blocknum; + ls->number_of_timeout++; + + /* Set the timeout time of the node.*/ + l_ulResult = OctApiLmAdd( current_time, 1, &timeout_value, 0, node->timeout, 1 ); + if (l_ulResult != GENERIC_OK) + return(l_ulResult); + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmCheckTimeoutList. +| +| Description: This function will verify if the timeout time +| of all the node present in the timeout list are bigger +| then the current time. If so the node will be returned +| ot the free node list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *ls TLLM_ALLOC The memory used by the TLLM_ALLOC structure. +| current_time UINT32[2] The current time in msec. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiTllmCheckTimeoutList +UINT32 OctApiTllmCheckTimeoutList(TLLM_ALLOC *ls, UINT32 current_time[2]) +{ + UINT32 result; + UINT32 fConditionFlag = TRUE; + + /* Free-up any pending memory before trying the allocation:*/ + if ((ls->last_known_time[0] != current_time[0] || + ls->last_known_time[1] != current_time[1]) && + (current_time[1] != 0 || current_time[0] != 0)) /* Time has changed.*/ + { + TLLM_ALLOC_NODE *pcurrent_node; + UINT32 current_num; + USHORT neg; + + /* Remember time for next time!*/ + ls->last_known_time[0] = current_time[0]; + ls->last_known_time[1] = current_time[1]; + + + while ( fConditionFlag == TRUE ) + { + /* Get a node from the timeout list.*/ + pcurrent_node = &ls->linked_list[ ls->next_timeout_num ]; + current_num = ls->next_timeout_num; + + /* Check if first node has timeout.*/ + result = OctApiLmCompare(current_time,1,pcurrent_node->timeout ,1,&neg); + if (result != GENERIC_OK) return(result); + + /* if the timeout tiem was exceeded, set the block as free.*/ + if ( neg == FALSE ) + { + /* set the next node pointer.*/ + ls->next_timeout_num = pcurrent_node->value; + ls->number_of_timeout--; + + /* reset the last pointer of the timeout list.*/ + if ( ls->number_of_timeout == 0 ) + ls->last_timeout_num = 0xFFFFFFFF; + + /* return the node the free list.*/ + pcurrent_node->value = ls->next_avail_num; + ls->next_avail_num = current_num; + ls->allocated_items--; + } + else /* node not in timeout */ + { + fConditionFlag = FALSE; + break; + } + + if ( ls->next_timeout_num == 0xFFFFFFFF ) + { + fConditionFlag = FALSE; + break; /* end of timeout list.*/ + } + } + } + + return(GENERIC_OK); +} +#endif +/**************************************** llm_alloc section **********************************************/ + + + + + + + +/**************************************** llm_list section **********************************************/ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListGetSize +| +| Description: This function determines the amount of memory needed by +| the LLM_LIST structure to manage the allocation of +| number_of_items number of resources. The memory is +| measured in bytes. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| number_of_items UINT32 The number of resources to be allocated +| amongst all linked-lists. +| number_of_lists UINT32 The maximum number of linked-lists that +| can be allocated. +| *l_size UINT32 UINT32 The amount of memory needed, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListGetSize +UINT32 OctApiLlmListGetSize(UINT32 number_of_items,UINT32 number_of_lists,UINT32 user_info_size,UINT32 * l_size) +{ + UINT32 head_alloc_size; + UINT32 result; + UINT32 user_info_size_roundup; + + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + if (number_of_lists == 0) return(GENERIC_BAD_PARAM); + if (user_info_size == 0) return(GENERIC_BAD_PARAM); + + user_info_size_roundup = ((user_info_size + 3) / 4) * 4; + + result = OctapiLlmAllocGetSize(number_of_lists,&head_alloc_size); + if(result != GENERIC_OK) return(result); + + *l_size = sizeof(LLM_LIST) + (number_of_lists * sizeof(LLM_LIST_HEAD)) + head_alloc_size + (number_of_items * (sizeof(LLM_LIST_ITEM) + user_info_size_roundup - 4)); + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiLlmListGetItemPointer +LLM_LIST_ITEM * OctApiLlmListGetItemPointer(LLM_LIST * ls, UINT32 item_number) +{ + return (LLM_LIST_ITEM *) (((BYTE *)ls->li) + (ls->item_size * item_number)) ; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListInit. +| +| Description: This function intializes the LLM_TALLOC structure. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| number_of_items UINT32 The number of resources to be allocated +| amongst all linked-lists. +| number_of_lists UINT32 The maximum number of linked-lists that +| can be allocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListInit +UINT32 OctApiLlmListInit(void ** l,UINT32 number_of_items,UINT32 number_of_lists,UINT32 user_info_size) +{ + LLM_LIST* ls; + LLM_LIST_ITEM* item; + UINT32 i; + UINT32 head_alloc_size; + UINT32 result; + UINT32 user_info_size_roundup; + UINT32 total_lists; + BYTE* lsbyte; + + + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + if (number_of_lists == 0) return(GENERIC_BAD_PARAM); + if (user_info_size == 0) return(GENERIC_BAD_PARAM); + + user_info_size_roundup = ((user_info_size + 3) / 4) * 4; + + /* Get the size of the Alloc structure used to manage head of list structures.*/ + result = OctapiLlmAllocGetSize(number_of_lists,&head_alloc_size); + if(result != GENERIC_OK) return(result); + + if (*l == NULL) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)(*l); + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + /* Initialize parameters in the structure.*/ + ls->head_alloc_size = head_alloc_size; + ls->user_info_bytes = user_info_size; + ls->user_info_size = user_info_size_roundup; + ls->total_items = number_of_items; + ls->assigned_items = 0; + ls->total_lists = number_of_lists; + ls->assigned_lists = 0; + ls->next_empty_item = 0; + ls->item_size = sizeof(LLM_LIST_ITEM) + user_info_size_roundup - 4; + + /* Complete the build!*/ + ls = (LLM_LIST *)(*l); + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + /* Initialize the head of queue Alloc structure.*/ + result = OctapiLlmAllocInit(&(ls->list_head_alloc),number_of_lists); + if(result != GENERIC_OK) return(result); + + /* Initialize the linked list of the items:*/ + for(i=0; ili + ls->item_size * i); + + if (i == (number_of_items - 1)) + item->forward_link = 0xFFFFFFFF; + else + item->forward_link = i + 1; + } + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListInfo. +| +| Description: This function returns the status of the LLM_LIST structure. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *allocated_lists UINT32 The number of linked_lists allocated. +| *free_lists UINT32 The number of linked_lists still free. +| *allocated_items UINT32 The number of items allocated to lists. +| *free_items UINT32 The number of items still free. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListInfo +UINT32 OctApiLlmListInfo(void * l,UINT32 * allocated_lists,UINT32 * allocated_items, + UINT32 * free_lists,UINT32 * free_items) +{ + LLM_LIST* ls; + BYTE* lsbyte; + UINT32 total_lists; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + *allocated_items = ls->assigned_items; + *free_items = ls->total_items - ls->assigned_items; + + *allocated_lists = ls->assigned_lists; + *free_lists = ls->total_lists - ls->assigned_lists; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListCreate. +| +| Description: This function creates a linked list. The target which is +| allocated the newly created list can request additions +| or removals from the list later on. To target identifies +| its list with the returned list handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the new list, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListCreate +UINT32 OctApiLlmListCreate(void * l,UINT32 * list_handle) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + UINT32 blocknum; + UINT32 total_lists; + UINT32 result; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + /* Get a list using the list head alloc structure.*/ + result = OctapiLlmAllocAlloc(ls->list_head_alloc, &blocknum); + if (result != GENERIC_OK) return(result); + + /* The handle is the block number.*/ + *list_handle = blocknum; + + /* Initialize the list head structure.*/ + lh = &ls->lh[blocknum]; + lh->list_length = 0; + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + lh->cache_item_number = 0xFFFFFFFF; + lh->cache_item_pointer = 0xFFFFFFFF; + + ls->assigned_lists++; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListDelete. +| +| Description: This function deletes the linked list indicated by the +| handle list_handle. Any items which are still allocated +| to the list are first deallocated. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the list. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListDelete +UINT32 OctApiLlmListDelete(void * l,UINT32 list_handle) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + UINT32 total_lists; + UINT32 result; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (ls->lh[list_handle].list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + /* Release internal list header handle...*/ + result = OctapiLlmAllocDealloc(ls->list_head_alloc,list_handle); + if (result != GENERIC_OK) return(result); + + lh = &ls->lh[list_handle]; + + /* Deallocate all items in the list!*/ + if (lh->list_length != 0) + { + LLM_LIST_ITEM * item; + + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->tail_pointer); + + /* Release the items using only the links.*/ + item->forward_link = ls->next_empty_item; + ls->next_empty_item = lh->head_pointer; + + /* Remove items from item counter.*/ + ls->assigned_items -= lh->list_length; + } + + lh->list_length = 0xFFFFFFFF; + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + lh->cache_item_number = 0xFFFFFFFF; + lh->cache_item_pointer = 0xFFFFFFFF; + + ls->assigned_lists--; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListLength. +| +| Description: This function returns the number of items allocated to the +| list indicated by the handle list_handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| list_handle UINT32 The handle to the list. +| *number_of_items UINT32 The number of items in the list, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListLength +UINT32 OctApiLlmListLength(void * l,UINT32 list_handle, UINT32 * number_of_items_in_list) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + UINT32 total_lists; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + *number_of_items_in_list = lh->list_length; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListItemData +| +| Description: This function returns a pointer to the user data associated +| with an item. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| list_handle UINT32 The handle to the list. +| item_number UINT32 The number of the list node in question. +| **item_data_pnt void The pointer to the user data, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListItemData +UINT32 OctApiLlmListItemData(void * l,UINT32 list_handle,UINT32 item_number,void ** item_data_pnt) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* item; + UINT32 cur_list_pnt; + UINT32 cur_list_num; + UINT32 total_lists; + UINT32 list_length; + BYTE* lsbyte; + UINT32 fConditionFlag = TRUE; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + list_length = lh->list_length; + + *item_data_pnt = NULL; + if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE); + if (list_length <= item_number) return(OCTAPI_LLM_ELEMENT_NOT_FOUND); + + /* Determine where the search will start.*/ + if (list_length == (item_number + 1)) /* Last item in list:*/ + { + cur_list_pnt = lh->tail_pointer; + cur_list_num = item_number; + } + else if (lh->cache_item_number <= item_number) /* Start at cache:*/ + { + cur_list_pnt = lh->cache_item_pointer; + cur_list_num = lh->cache_item_number; + } + else /* Start at beginning:*/ + { + cur_list_pnt = lh->head_pointer; + cur_list_num = 0; + } + + /* Start search from cur_list_pnt and cur_list_num.*/ + while ( fConditionFlag == TRUE ) + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + + if (cur_list_num == item_number) /* Item number found.*/ + { + /* Write new cache entry.*/ + lh->cache_item_pointer = cur_list_pnt; + lh->cache_item_number = cur_list_num; + + /* Get item info.*/ + *item_data_pnt = (void *)item->user_info; + + return(GENERIC_OK); + } + else if(item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/ + { + return(OCTAPI_LLM_INTERNAL_ERROR0); + } + else /* Item was not found, but continue searching.*/ + { + cur_list_pnt = item->forward_link; + } + + cur_list_num++; + } + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListInsertItem. +| +| Description: This function allocates a node to the linked list specified +| by the handle list_handle. The position of the new item +| can be specified. A position of 0xFFFFFFFF means append to the +| list( use the OCTAPI_LLM_LIST_APPEND define for clarity); +| a position of 0 mean insert at the begining of the list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the list. +| **item_data void Address of the user data space for this item. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListInsertItem +UINT32 OctApiLlmListInsertItem(void * l,UINT32 list_handle,UINT32 item_number,void ** item_data_pnt) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* free_item; + UINT32 free_item_pnt; + UINT32 total_lists; + BYTE* lsbyte; + UINT32 fConditionFlag = TRUE; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + *item_data_pnt = NULL; + if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE); + if (lh->list_length < item_number && item_number != 0xFFFFFFFF) + return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (ls->next_empty_item == 0xFFFFFFFF) return(OCTAPI_LLM_NO_STRUCTURES_LEFT); + + /* Get a free item from the free item list!*/ + free_item_pnt = ls->next_empty_item; + free_item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * free_item_pnt); + ls->next_empty_item = free_item->forward_link; + + if (item_number == 0xFFFFFFFF) + item_number = lh->list_length; + + if (lh->list_length == 0) /* First item and only item:*/ + { + free_item->forward_link = 0xFFFFFFFF; + lh->tail_pointer = free_item_pnt; + lh->head_pointer = free_item_pnt; + } + else if (item_number == 0) /* First item and but list not empty:*/ + { + free_item->forward_link = lh->head_pointer; + lh->head_pointer = free_item_pnt; + } + else if (item_number == lh->list_length) /* Append:*/ + { + LLM_LIST_ITEM * last_item; + last_item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->tail_pointer); + + last_item->forward_link = free_item_pnt; + free_item->forward_link = 0xFFFFFFFF; + lh->tail_pointer = free_item_pnt; + } + else /* Insert:*/ + { + LLM_LIST_ITEM * last_item = NULL; + LLM_LIST_ITEM * item; + UINT32 last_list_pnt; + UINT32 cur_list_pnt; + UINT32 cur_list_num; + + if (lh->cache_item_number < item_number) /* Start at cache:*/ + { + cur_list_pnt = lh->cache_item_pointer; + cur_list_num = lh->cache_item_number; + } + else /* Start at beginning:*/ + { + cur_list_pnt = lh->head_pointer; + cur_list_num = 0; + } + + last_list_pnt = 0xFFFFFFFF; + + /* Start search from cur_list_pnt and cur_list_num.*/ + while ( fConditionFlag == TRUE ) + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + + if (cur_list_num == item_number) /* Item number found.*/ + { + if (last_list_pnt == 0xFFFFFFFF) return(OCTAPI_LLM_INTERNAL_ERROR1); + + free_item->forward_link = cur_list_pnt; + last_item->forward_link = free_item_pnt; + + fConditionFlag = FALSE; + break; + } + else if (item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/ + { + return(OCTAPI_LLM_INTERNAL_ERROR0); + } + else /* Item was not found, but continue searching.*/ + { + last_item = item; + last_list_pnt = cur_list_pnt; + cur_list_pnt = item->forward_link; + } + + cur_list_num++; + } + } + + /* Increase the list length.*/ + lh->list_length++; + ls->assigned_items++; + *item_data_pnt = (void *)free_item->user_info; + + /* Write new cache entry.*/ + lh->cache_item_pointer = free_item_pnt; + lh->cache_item_number = item_number; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListCreateFull. +| +| Description: This function allocates the desired number of nodes to +| the linked list specified by the handle list_handle. +| The position of the new item can be specified. A +| position of 0xFFFFFFFF means append to the list (use the +| OCTAPI_LLM_LIST_APPEND define for clarity); a position +| of 0 means insert at the begining of the list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the list. +| **item_data void Address of the user data space for this item. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListCreateFull +UINT32 OctApiLlmListCreateFull(void* l, UINT32 list_length, UINT32* plist_handle) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* free_item; + LLM_LIST_ITEM* last_item = NULL; + UINT32 free_item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + UINT32 list_handle; + UINT32 list_length_m1; + UINT32 next_empty_item; + UINT32 result; + UINT32 i; + BYTE* lsbyte; + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Build the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Make sure another list can be created.*/ + if (ls->assigned_lists == ls->total_lists) + return(OCTAPI_LLM_ELEMENT_ALREADY_ASSIGNED); + + /* Make sure there are enough free nodes to fill the new list.*/ + if (list_length > (ls->total_items - ls->assigned_items)) + return(OCTAPI_LLM_ELEMENT_ALREADY_ASSIGNED); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Create list (i.e. get a list using the list head alloc structure.*/ + result = OctapiLlmAllocAlloc(ls->list_head_alloc, &list_handle); + if (result != GENERIC_OK) return(result); + + /* Initialize the list head structure.*/ + lh = &ls->lh[list_handle]; + lh->list_length = 0; + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + lh->cache_item_number = 0xFFFFFFFF; + lh->cache_item_pointer = 0xFFFFFFFF; + + ls->assigned_lists++; + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Add the number of requested nodes to the list.*/ + lh = &ls->lh[list_handle]; + list_length_m1 = list_length - 1; + next_empty_item = ls->next_empty_item; + + for (i=0; ili + ls->item_size * free_item_pnt); + next_empty_item = free_item->forward_link; + + /* Branch according to whether the node is the first in list, last, or in + the middle.*/ + if (i == 0) + { + /* First item.*/ + free_item->forward_link = 0xFFFFFFFF; + lh->head_pointer = free_item_pnt; + lh->tail_pointer = free_item_pnt; + } + else if (i == list_length_m1) + { + /* Last item.*/ + last_item->forward_link = free_item_pnt; + free_item->forward_link = 0xFFFFFFFF; + lh->tail_pointer = free_item_pnt; + } + else + { + /* Node somewhere in the middle.*/ + last_item->forward_link = free_item_pnt; + } + + /* Store pointer to free item as pointer to last item (for next iteration).*/ + last_item = free_item; + } + + /* Store new value of next_empty_item.*/ + ls->next_empty_item = next_empty_item; + + /* Write new cache entry.*/ + lh->cache_item_pointer = free_item_pnt; + lh->cache_item_number = list_length_m1; + + /* Set the list length.*/ + lh->list_length = list_length; + ls->assigned_items += list_length; + + /* Return pointer to new list.*/ + *plist_handle = list_handle; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListAppendItems. +| +| Description: This function allocates the desired number of nodes to +| the linked list specified by the handle list_handle. +| The position of the new item can be specified. A +| position of 0xFFFFFFFF means append to the list (use the +| OCTAPI_LLM_LIST_APPEND define for clarity); a position +| of 0 means insert at the begining of the list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the list. +| **item_data void Address of the user data space for this item. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListAppendItems +UINT32 OctApiLlmListAppendItems(void* l, UINT32 list_handle, UINT32 num_items) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* item_list; + LLM_LIST_ITEM* curr_item = NULL; + LLM_LIST_ITEM* free_item; + UINT32 curr_item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + UINT32 next_empty_item; + UINT32 item_size; + UINT32 i; + BYTE* lsbyte; + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Build the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Make sure list handle is valid.*/ + if (list_handle >= ls->total_lists) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + /* Make sure there is at least one item.*/ + if (num_items == 0) + return(OCTAPI_LLM_INVALID_PARAMETER); + + /* Make sure there are enough free nodes.*/ + if (num_items > (ls->total_items - ls->assigned_items)) + return(OCTAPI_LLM_NO_STRUCTURES_LEFT); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Get pointer to list structure.*/ + lh = &ls->lh[list_handle]; + if (lh->list_length == 0xFFFFFFFF) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Add the number of requested nodes to the list.*/ + item_list = ls->li; + item_size = ls->item_size; + next_empty_item = ls->next_empty_item; + + for (i=0; ihead_pointer == 0xFFFFFFFF) + { + /* Current and next items are one and the same!*/ + curr_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Set new head and tail pointers.*/ + lh->head_pointer = next_empty_item; + lh->tail_pointer = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next item.*/ + next_empty_item = curr_item->forward_link; + + /* Set first item to be only item in list.*/ + curr_item->forward_link = 0xFFFFFFFF; + } + else + { + /* Get a free item from the free item list!*/ + curr_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * lh->tail_pointer); + free_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Have current item point to next empty item.*/ + curr_item->forward_link = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next_empty_item.*/ + next_empty_item = free_item->forward_link; + + /* Update pointers to current item and free item.*/ + curr_item = free_item; + } + } + else + { + /* Update pointers to current item and free item.*/ + free_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Have current item point to next empty item.*/ + curr_item->forward_link = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next_empty_item.*/ + next_empty_item = free_item->forward_link; + + /* Update pointers to current item and free item.*/ + curr_item = free_item; + } + } + + /* Terminate list.*/ + if ( curr_item != NULL ) + curr_item->forward_link = 0xFFFFFFFF; + + /* Update llman structure variables.*/ + ls->next_empty_item = next_empty_item; + ls->assigned_items += num_items; + + /* Update list variables.*/ + lh->list_length += num_items; + lh->cache_item_pointer = curr_item_pnt; + lh->cache_item_number = lh->list_length - 1; + lh->tail_pointer = curr_item_pnt; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListAppendAndSetItems. +| +| Description: +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListAppendAndSetItems +UINT32 OctApiLlmListAppendAndSetItems(void* l, UINT32 list_handle, UINT32 num_items, void* data_list) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* item_list; + LLM_LIST_ITEM* curr_item = NULL; + LLM_LIST_ITEM* free_item; + UINT32 curr_item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + UINT32 next_empty_item; + UINT32 user_info_bytes; + UINT32 item_size; + UINT32 i; + BYTE* lsbyte; + void* data_item; + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Build the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Make sure list handle is valid.*/ + if (list_handle >= ls->total_lists) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + /* Make sure there is at least one item.*/ + if (num_items == 0) + return(OCTAPI_LLM_INVALID_PARAMETER); + + /* Make sure there are enough free nodes.*/ + if (num_items > (ls->total_items - ls->assigned_items)) + return(OCTAPI_LLM_NO_STRUCTURES_LEFT); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Get pointer to list structure.*/ + lh = &ls->lh[list_handle]; + if (lh->list_length == 0xFFFFFFFF) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Add the number of requested nodes to the list.*/ + item_list = ls->li; + user_info_bytes = ls->user_info_bytes; + item_size = ls->item_size; + next_empty_item = ls->next_empty_item; + data_item = data_list; + + for (i=0; ihead_pointer == 0xFFFFFFFF) + { + /* Current and next items are one and the same!*/ + curr_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Set new head and tail pointers.*/ + lh->head_pointer = next_empty_item; + lh->tail_pointer = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next item.*/ + next_empty_item = curr_item->forward_link; + + /* Set first item to be only item in list.*/ + curr_item->forward_link = 0xFFFFFFFF; + } + else + { + /* Get a free item from the free item list!*/ + curr_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * lh->tail_pointer); + free_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Have current item point to next empty item.*/ + curr_item->forward_link = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next_empty_item.*/ + next_empty_item = free_item->forward_link; + + /* Update pointers to current item and free item.*/ + curr_item = free_item; + } + } + else + { + /* Update pointers to current item and free item.*/ + free_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Have current item point to next empty item.*/ + curr_item->forward_link = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next_empty_item.*/ + next_empty_item = free_item->forward_link; + + /* Update pointers to current item and free item.*/ + curr_item = free_item; + } + + /* Copy data to new item.*/ + OctApiLlmMemCpy(curr_item->user_info, data_item, user_info_bytes); + + /* Update data_item pointer for next iteration (item).*/ + data_item = (void *)((BYTE *)data_item + user_info_bytes); + } + + + /* Terminate list.*/ + if ( curr_item != NULL ) + curr_item->forward_link = 0xFFFFFFFF; + + /* Update llman structure variables.*/ + ls->next_empty_item = next_empty_item; + ls->assigned_items += num_items; + + /* Update list variables.*/ + lh->list_length += num_items; + lh->cache_item_pointer = curr_item_pnt; + lh->cache_item_number = lh->list_length - 1; + lh->tail_pointer = curr_item_pnt; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListSetItems. +| +| Description: This function takes a start entry (0 to length - 1), +| a pointer to a list of data (each item of list is the +| size of one data unit, specified at init), and the +| length of the data list. From this, the data will be +| copied from the data list to the linked list, from +| entry start_entry to (start_entry + data_length - 1). +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListSetItems +UINT32 OctApiLlmListSetItems(void* l, UINT32 list_handle, UINT32 start_item, UINT32 data_length, void* pdata_list) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* item = NULL; + UINT32 total_lists; + UINT32 item_pnt = 0xFFFFFFFF; + UINT32 i, j; + BYTE* lsbyte; + void* pdata_item = NULL; + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Build the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Make sure list handle is valid.*/ + if (list_handle >= ls->total_lists) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + lh = &ls->lh[list_handle]; + if (lh->list_length == 0xFFFFFFFF) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + /* Make sure the start_entry is within limits.*/ + if (start_item >= lh->list_length) + return(OCTAPI_LLM_INVALID_PARAMETER); + + /* Make sure the end_entry is within limits.*/ + lh = &ls->lh[list_handle]; + if ((start_item + data_length) > lh->list_length) + return(OCTAPI_LLM_INVALID_PARAMETER); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Set the data of each node.*/ + for (i=0; icache_item_number + 1)) + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->cache_item_pointer); + item_pnt = item->forward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + } + else + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->head_pointer); + item_pnt = lh->head_pointer; + for (j=0; jforward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + } + } + + pdata_item = (void *)((BYTE *)pdata_list + (i * ls->user_info_bytes)); + } + else + { + item_pnt = item->forward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + + pdata_item = (void *)((BYTE *)pdata_item + ls->user_info_bytes); + } + + /* Set the value of the item's user data.*/ + OctApiLlmMemCpy(item->user_info, pdata_item, ls->user_info_bytes); + } + + /* Write new cache entry.*/ + lh->cache_item_pointer = item_pnt; + lh->cache_item_number = start_item + data_length - 1; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListCopyData. +| +| Description: This function takes a start entry (0 to length - 1), +| a pointer to a list of data (each item of list is the +| size of one data unit, specified at init), and the +| length of the data list. From this, the data will be +| copied from the linked list to the data list, from +| entry start_entry of the linked list to +| (start_entry + data_length - 1). +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListCopyData +UINT32 OctApiLlmListCopyData(void* l, UINT32 list_handle, UINT32 start_item, UINT32 data_length, void* pdata_list) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* item = NULL; + UINT32 item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + UINT32 i, j; + BYTE* lsbyte; + void* pdata_item = NULL; + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Build the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Make sure list handle is valid.*/ + if (list_handle >= ls->total_lists) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + lh = &ls->lh[list_handle]; + if (lh->list_length == 0xFFFFFFFF) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + /* Make sure the start_entry is within limits.*/ + if (start_item >= lh->list_length) + return(OCTAPI_LLM_INVALID_PARAMETER); + + /* Make sure the end_entry is within limits.*/ + lh = &ls->lh[list_handle]; + if ((start_item + data_length) > lh->list_length) + return(OCTAPI_LLM_INVALID_PARAMETER); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Set the data of each node.*/ + for (i=0; icache_item_number + 1)) + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->cache_item_pointer); + item_pnt = item->forward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + } + else + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->head_pointer); + for (j=0; jforward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + } + } + + pdata_item = (void *)((BYTE *)pdata_list + (i * ls->user_info_bytes)); + } + else + { + item_pnt = item->forward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + + pdata_item = (void *)((BYTE *)pdata_item + ls->user_info_bytes); + } + + /* Set the value of the item's user data.*/ + OctApiLlmMemCpy(pdata_item, item->user_info, ls->user_info_bytes); + } + + /* Write new cache entry.*/ + lh->cache_item_pointer = item_pnt; + lh->cache_item_number = start_item + data_length - 1; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListRemoveItem. +| +| Description: This function deallocates a node of the linked list specified +| by the handle list_handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| list_handle UINT32 The handle to the list. +| item_number UINT32 The number of the item to be removed. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListRemoveItem +UINT32 OctApiLlmListRemoveItem(void * l,UINT32 list_handle,UINT32 item_number) +{ + LLM_LIST* ls; + LLM_LIST_ITEM* freed_item = NULL; + LLM_LIST_HEAD* lh; + UINT32 freed_item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + BYTE* lsbyte; + UINT32 fConditionFlag = TRUE; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE); + if (lh->list_length <= item_number) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + + if (item_number == 0 && lh->list_length == 1)/* First item and only item:*/ + { + freed_item_pnt = lh->head_pointer; + freed_item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * freed_item_pnt); + + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + + lh->cache_item_number = 0xFFFFFFFF; + lh->cache_item_pointer = 0xFFFFFFFF; + } + else if (item_number == 0) /* First item and but list not empty:*/ + { + freed_item_pnt = ls->lh[list_handle].head_pointer; + freed_item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * freed_item_pnt); + + lh->head_pointer = freed_item->forward_link; + + lh->cache_item_number = 0; + lh->cache_item_pointer = freed_item->forward_link; + } + else /* Discard non-first item! (Caution: this could be the last item!)*/ + { + LLM_LIST_ITEM * last_item = NULL; + LLM_LIST_ITEM * item; + UINT32 last_list_pnt; + UINT32 cur_list_pnt; + UINT32 cur_list_num; + + if (lh->cache_item_number < item_number) /* Start at cache:*/ + { + cur_list_pnt = lh->cache_item_pointer; + cur_list_num = lh->cache_item_number; + } + else /* Start at beginning:*/ + { + cur_list_pnt = lh->head_pointer; + cur_list_num = 0; + } + + last_list_pnt = 0xFFFFFFFF; + + /* Start search from cur_list_pnt and cur_list_num.*/ + while( fConditionFlag == TRUE ) + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + + if (cur_list_num == item_number) /* Item number found.*/ + { + if (last_list_pnt == 0xFFFFFFFF) return(OCTAPI_LLM_INTERNAL_ERROR1); + + if ((item_number + 1) == lh->list_length) + { + lh->tail_pointer = last_list_pnt; + last_item->forward_link = 0xFFFFFFFF; + } + else + { + last_item->forward_link = item->forward_link; + } + freed_item_pnt = cur_list_pnt; + freed_item = item; + + /* Reset cache entry.*/ + lh->cache_item_pointer = last_list_pnt; + lh->cache_item_number = cur_list_num - 1; + + fConditionFlag = FALSE; + break; + } + else if (item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/ + { + return(OCTAPI_LLM_INTERNAL_ERROR0); + } + else /* Item was not found, but continue searching.*/ + { + last_item = item; + last_list_pnt = cur_list_pnt; + cur_list_pnt = item->forward_link; + } + + cur_list_num++; + } + } + + /* Decrease the list length.*/ + lh->list_length--; + ls->assigned_items--; + + /* Return free block to free block list:*/ + freed_item->forward_link = ls->next_empty_item; + ls->next_empty_item = freed_item_pnt; + + return(GENERIC_OK); +} +#endif + +/**************************************** llm2 function section *****************************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListGetSize +| +| Description: This function determines the amount of memory needed by +| the LLM2_LIST structure to manage the allocation of +| number_of_items number of resources. The memory is +| measured in bytes. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| number_of_items UINT32 The number of resources to be allocated +| amongst all linked-lists. +| number_of_lists UINT32 The maximum number of linked-lists that +| can be allocated. +| *l_size UINT32 UINT32 The amount of memory needed, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListGetSize +UINT32 OctApiLlm2ListGetSize(UINT32 number_of_items,UINT32 number_of_lists,UINT32 user_info_size,UINT32 * l_size) +{ + UINT32 head_alloc_size; + UINT32 result; + UINT32 user_info_size_roundup; + + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + if (number_of_lists == 0) return(GENERIC_BAD_PARAM); + if (user_info_size == 0) return(GENERIC_BAD_PARAM); + + user_info_size_roundup = ((user_info_size + 3) / 4) * 4; + + result = OctapiLlmAllocGetSize(number_of_lists,&head_alloc_size); + if(result != GENERIC_OK) return(result); + + *l_size = sizeof(LLM2_LIST) + (number_of_lists * sizeof(LLM2_LIST_HEAD)) + head_alloc_size + (number_of_items * (sizeof(LLM2_LIST_ITEM) + user_info_size_roundup - 4)); + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiLlm2ListGetItemPointer +LLM2_LIST_ITEM * OctApiLlm2ListGetItemPointer(LLM2_LIST * ls, UINT32 item_number) +{ + return (LLM2_LIST_ITEM *) (((BYTE *)ls->li) + (ls->item_size * item_number)) ; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListInit. +| +| Description: This function intializes the LLM2_TALLOC structure. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| number_of_items UINT32 The number of resources to be allocated +| amongst all linked-lists. +| number_of_lists UINT32 The maximum number of linked-lists that +| can be allocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListInit +UINT32 OctApiLlm2ListInit(void ** l,UINT32 number_of_items,UINT32 number_of_lists,UINT32 user_info_size) +{ + LLM2_LIST* ls; + LLM2_LIST_ITEM* item; + UINT32 i; + UINT32 head_alloc_size; + UINT32 result; + UINT32 user_info_size_roundup; + UINT32 total_lists; + BYTE* lsbyte; + + + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + if (number_of_lists == 0) return(GENERIC_BAD_PARAM); + if (user_info_size == 0) return(GENERIC_BAD_PARAM); + + user_info_size_roundup = ((user_info_size + 3) / 4) * 4; + + /* Get the size of the Alloc structure used to manage head of list structures.*/ + result = OctapiLlmAllocGetSize(number_of_lists,&head_alloc_size); + if(result != GENERIC_OK) return(result); + + if (*l == NULL) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)(*l); + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + /* Initialize parameters in the structure.*/ + ls->head_alloc_size = head_alloc_size; + ls->user_info_bytes = user_info_size; + ls->user_info_size = user_info_size_roundup; + ls->total_items = number_of_items; + ls->assigned_items = 0; + ls->total_lists = number_of_lists; + ls->assigned_lists = 0; + ls->next_empty_item = 0; + ls->item_size = sizeof(LLM2_LIST_ITEM) + user_info_size_roundup - 4; + + /* Complete the build!*/ + ls = (LLM2_LIST *)(*l); + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + /* Initialize the head of queue Alloc structure.*/ + result = OctapiLlmAllocInit(&(ls->list_head_alloc),number_of_lists); + if(result != GENERIC_OK) return(result); + + /* Initialize the linked list of the items:*/ + for(i=0; ili + ls->item_size * i); + + if (i == (number_of_items - 1)) + item->forward_link = 0xFFFFFFFF; + else + item->forward_link = i + 1; + } + + return(GENERIC_OK); +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListCreate. +| +| Description: This function creates a linked list. The target which is +| allocated the newly created list can request additions +| or removals from the list later on. To target identifies +| its list with the returned list handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the new list, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListCreate +UINT32 OctApiLlm2ListCreate(void * l,UINT32 * list_handle) +{ + LLM2_LIST* ls; + LLM2_LIST_HEAD* lh; + UINT32 blocknum; + UINT32 total_lists; + UINT32 result; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + /* Get a list using the list head alloc structure.*/ + result = OctapiLlmAllocAlloc(ls->list_head_alloc, &blocknum); + if (result != GENERIC_OK) return(result); + + /* The handle is the block number.*/ + *list_handle = blocknum; + + /* Initialize the list head structure.*/ + lh = &ls->lh[blocknum]; + lh->list_length = 0; + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + + ls->assigned_lists++; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListDelete. +| +| Description: This function deletes the linked list indicated by the +| handle list_handle. Any items which are still allocated +| to the list are first deallocated. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| *list_handle UINT32 The handle to the list. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListDelete +UINT32 OctApiLlm2ListDelete(void * l,UINT32 list_handle) +{ + LLM2_LIST* ls; + LLM2_LIST_HEAD* lh; + UINT32 total_lists; + UINT32 result; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE); + if (ls->lh[list_handle].list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE); + + /* Release internal list header handle...*/ + result = OctapiLlmAllocDealloc(ls->list_head_alloc,list_handle); + if (result != GENERIC_OK) return(result); + + lh = &ls->lh[list_handle]; + + /* Deallocate all items in the list!*/ + if (lh->list_length != 0) + { + LLM2_LIST_ITEM * item; + + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->tail_pointer); + + /* Release the items using only the links.*/ + item->forward_link = ls->next_empty_item; + ls->next_empty_item = lh->head_pointer; + + /* Remove items from item counter.*/ + ls->assigned_items -= lh->list_length; + } + + lh->list_length = 0xFFFFFFFF; + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + + ls->assigned_lists--; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListLength. +| +| Description: This function returns the number of items allocated to the +| list indicated by the handle list_handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| list_handle UINT32 The handle to the list. +| *number_of_items UINT32 The number of items in the list, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListLength +UINT32 OctApiLlm2ListLength(void * l,UINT32 list_handle, UINT32 * number_of_items_in_list) +{ + LLM2_LIST* ls; + LLM2_LIST_HEAD* lh; + UINT32 total_lists; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE); + + *number_of_items_in_list = lh->list_length; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListItemData +| +| Description: This function returns a pointer to the user data associated +| with an item. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| list_handle UINT32 The handle to the list. +| item_number UINT32 The number of the list node in question. +| **item_data_pnt void The pointer to the user data, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListItemData +UINT32 OctApiLlm2ListItemData(void * l,UINT32 list_handle,UINT32 item_key,void ** item_data_pnt, PUINT32 item_number_pnt) +{ + LLM2_LIST* ls; + LLM2_LIST_HEAD* lh; + LLM2_LIST_ITEM* item; + UINT32 cur_list_pnt; + UINT32 cur_list_key = 0xFFFFFFFF; + UINT32 total_lists; + UINT32 list_length; + BYTE* lsbyte; + UINT32 fConditionFlag = TRUE; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + list_length = lh->list_length; + + *item_data_pnt = NULL; + *item_number_pnt = 0; + if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE); + if (list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE); + + /* Determine where the search will start.*/ + /* Start at beginning:*/ + cur_list_pnt = lh->head_pointer; + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + + /* Start search from cur_list_pnt and cur_list_num.*/ + while ( fConditionFlag == TRUE ) + { + if (cur_list_key == item_key) /* Item key found.*/ + { + /* Get item info.*/ + *item_data_pnt = (void *)item->user_info; + + return(GENERIC_OK); + } + else if(item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/ + { + return(OCTAPI_LLM2_INTERNAL_ERROR0); + } + else /* Item was not found, but continue searching.*/ + { + cur_list_pnt = item->forward_link; + } + + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + (*item_number_pnt)++; + } + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListInsertItem. +| +| Description: This function allocates a node to the linked list specified +| by the handle list_handle. The position of the new item +| will be defined based on the key value. All entry are inserted +| in the list in incremental Key value. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| *list_handle UINT32 The handle to the list. +| **item_data void Address of the user data space for this item. +| **prev_item_data void Address of the user data space for the previous item. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListInsertItem +UINT32 OctApiLlm2ListInsertItem(void * l,UINT32 list_handle,UINT32 item_key,void ** item_data_pnt, void ** prev_item_data_pnt, void ** prev_prev_item_data_pnt, PUINT32 insert_status_pnt ) +{ + LLM2_LIST* ls; + LLM2_LIST_HEAD* lh; + LLM2_LIST_ITEM* free_item; + UINT32 free_item_pnt; + UINT32 total_lists; + BYTE* lsbyte; + UINT32 ulPassCount = 0; + UINT32 fConditionFlag = TRUE; + + /* Set the status of the insertion.*/ + *insert_status_pnt = OCTAPI_LLM2_INSERT_ERROR; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + *item_data_pnt = NULL; + if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE); + if (ls->next_empty_item == 0xFFFFFFFF) return(OCTAPI_LLM2_NO_STRUCTURES_LEFT); + + /* Get a free item from the free item list!*/ + free_item_pnt = ls->next_empty_item; + free_item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * free_item_pnt); + free_item->key = item_key; + ls->next_empty_item = free_item->forward_link; + + if (lh->list_length == 0) /* First item and only item:*/ + { + free_item->forward_link = 0xFFFFFFFF; + lh->tail_pointer = free_item_pnt; + lh->head_pointer = free_item_pnt; + *insert_status_pnt = OCTAPI_LLM2_INSERT_FIRST_NODE; + + /* There is no previous node information to return.*/ + *prev_item_data_pnt = NULL; + *prev_prev_item_data_pnt = NULL; + } + else /* Insert:*/ + { + LLM2_LIST_ITEM * last_last_item = NULL; + LLM2_LIST_ITEM * last_item = NULL; + LLM2_LIST_ITEM * item; + UINT32 last_list_pnt; + UINT32 cur_list_pnt; + UINT32 cur_list_key = 0xFFFFFFFF; + + /* Start at beginning:*/ + cur_list_pnt = lh->head_pointer; + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + + last_list_pnt = 0xFFFFFFFF; + + /* Start search from cur_list_pnt and cur_list_num.*/ + while ( fConditionFlag == TRUE ) + { + /* Increment the pass count to determine if the addition will happen next to last.*/ + ulPassCount++; + + if (cur_list_key >= item_key) /* Item new node between the last and the curent. */ + { + if (last_list_pnt == 0xFFFFFFFF) /* Must insert at the head of the list.*/ + { + free_item->forward_link = cur_list_pnt; + lh->head_pointer = free_item_pnt; + } + else /* Standard insertion.*/ + { + free_item->forward_link = cur_list_pnt; + last_item->forward_link = free_item_pnt; + } + + /* Check if the entry was made before the last one.*/ + if ( ulPassCount == lh->list_length ) + *insert_status_pnt = OCTAPI_LLM2_INSERT_BEFORE_LAST_NODE; + else + *insert_status_pnt = OCTAPI_LLM2_INSERT_LIST_NODE; + + fConditionFlag = FALSE; + break; + } + else if (item->forward_link == 0xFFFFFFFF) /* End of list found, must insert at the end.*/ + { + free_item->forward_link = 0xFFFFFFFF; + item->forward_link = free_item_pnt; + lh->tail_pointer = free_item_pnt; + + *insert_status_pnt = OCTAPI_LLM2_INSERT_LAST_NODE; + + fConditionFlag = FALSE; + break; + } + else /* Item was not found, but continue searching.*/ + { + last_last_item = last_item; + last_item = item; + last_list_pnt = cur_list_pnt; + cur_list_pnt = item->forward_link; + } + + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + + } + + /* Return the previous node if possible.*/ + if ( *insert_status_pnt == OCTAPI_LLM2_INSERT_LIST_NODE || + *insert_status_pnt == OCTAPI_LLM2_INSERT_BEFORE_LAST_NODE ) + { + if ( last_item != NULL ) + *prev_item_data_pnt = (void *)last_item->user_info; + + if ( last_last_item != NULL ) + *prev_prev_item_data_pnt = (void *)last_last_item->user_info; + else + *prev_prev_item_data_pnt = NULL; + } + else + { + *prev_item_data_pnt = (void *)item->user_info; + + if ( ( last_last_item != NULL ) && ( last_item != NULL ) ) + *prev_prev_item_data_pnt = (void *)last_item->user_info; + else + *prev_prev_item_data_pnt = NULL; + } + } + + /* Increase the list length.*/ + lh->list_length++; + ls->assigned_items++; + *item_data_pnt = (void *)free_item->user_info; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListRemoveItem. +| +| Description: This function deallocates a node of the linked list specified +| by the handle list_handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| list_handle UINT32 The handle to the list. +| item_key UINT32 The key of the item to be removed. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListRemoveItem +UINT32 OctApiLlm2ListRemoveItem(void * l,UINT32 list_handle,UINT32 item_key, PUINT32 prev_item_key_pnt, PUINT32 prev_prev_item_key_pnt, PUINT32 remove_status_pnt ) +{ + LLM2_LIST* ls; + LLM2_LIST_ITEM* freed_item = NULL; + LLM2_LIST_HEAD* lh; + UINT32 freed_item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + BYTE* lsbyte; + UINT32 fConditionFlag = TRUE; + UINT32 ulPassCount = 0; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + /* Set the status of the removal to error as a default value.*/ + *remove_status_pnt = OCTAPI_LLM2_REMOVE_ERROR; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE); + + if (lh->list_length == 1)/* First item and only item if he matches.*/ + { + freed_item_pnt = lh->head_pointer; + freed_item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * freed_item_pnt); + + if ( freed_item->key == item_key ) + { + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + } + else + return(OCTAPI_LLM2_INTERNAL_ERROR1); + + /* Indicate that there was no node prior to the one removed.*/ + *prev_item_key_pnt = 0xFFFFFFFF; + *prev_prev_item_key_pnt = 0xFFFFFFFF; + *remove_status_pnt = OCTAPI_LLM2_REMOVE_FIRST_NODE; + } + else /* Discard non-first item! (Caution: this could be the last item!)*/ + { + LLM2_LIST_ITEM * last_last_item = NULL; + LLM2_LIST_ITEM * last_item = NULL; + LLM2_LIST_ITEM * item; + UINT32 last_list_pnt; + UINT32 cur_list_pnt; + UINT32 cur_list_key; + + /* Start at beginning:*/ + cur_list_pnt = lh->head_pointer; + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + + last_list_pnt = 0xFFFFFFFF; + + /* Start search from cur_list_pnt and cur_list_num.*/ + while( fConditionFlag == TRUE ) + { + ulPassCount++; + if (cur_list_key == item_key) /* Item number found.*/ + { + if (last_list_pnt == 0xFFFFFFFF) /* First item in the list.*/ + { + lh->head_pointer = item->forward_link; + *remove_status_pnt = OCTAPI_LLM2_REMOVE_FIRST_NODE; + } + else if ( item->forward_link == 0xFFFFFFFF) /* Last item of the list.*/ + { + last_item->forward_link = 0xFFFFFFFF; + lh->tail_pointer = last_list_pnt; + *remove_status_pnt = OCTAPI_LLM2_REMOVE_LAST_NODE; + } + else + { + last_item->forward_link = item->forward_link; + + if ( ulPassCount == ( lh->list_length - 1 ) ) + *remove_status_pnt = OCTAPI_LLM2_REMOVE_BEFORE_LAST_NODE; + else + *remove_status_pnt = OCTAPI_LLM2_REMOVE_LIST_NODE; + } + + freed_item_pnt = cur_list_pnt; + freed_item = item; + + fConditionFlag = FALSE; + break; + } + else if (item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/ + { + return(OCTAPI_LLM2_INTERNAL_ERROR0); + } + else /* Item was not found, but continue searching.*/ + { + last_last_item = last_item; + last_item = item; + last_list_pnt = cur_list_pnt; + cur_list_pnt = item->forward_link; + } + + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + } + + /* Return the key of the node before the node removed if possible.*/ + if ( last_list_pnt == 0xFFFFFFFF ) + *prev_item_key_pnt = 0xFFFFFFFF; + else if ( last_item != NULL ) + *prev_item_key_pnt = last_item->key; + + /* Return the key of the node before before the node removed if possible.*/ + if ( last_last_item == NULL ) + *prev_prev_item_key_pnt = 0xFFFFFFFF; + else + *prev_prev_item_key_pnt = last_last_item->key; + + } + + /* Decrease the list length.*/ + lh->list_length--; + ls->assigned_items--; + + /* Return free block to free block list:*/ + freed_item->forward_link = ls->next_empty_item; + ls->next_empty_item = freed_item_pnt; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmMemCpy. +| +| Description: This function copies data from a source to a destination. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *f_pvDestination VOID The destination where to copy the data. +| *f_pvSource VOID The source where to copy the data from. +| f_ulSize UINT32 The number of bytes to copy. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmMemCpy +VOID * OctApiLlmMemCpy( VOID *f_pvDestination, const VOID * f_pvSource, UINT32 f_ulSize ) +{ + CHAR * pbyDst; + const CHAR * pbySrc; + UINT32 * f_pulAlignedDst; + const UINT32 * f_pulAlignedSrc; + + pbyDst = (CHAR *)f_pvDestination; + pbySrc = (const CHAR *)f_pvSource; + + /* + * If the size is small, or either SRC or DST is unaligned, + * then punt into the byte copy loop. This should be rare. + */ + if ( ( f_ulSize < sizeof(UINT32) ) + || ( ( (unsigned long)( pbySrc ) & ( sizeof(UINT32) - 1 ) ) | ( (unsigned long)( pbyDst ) & ( sizeof(UINT32) - 1 ) ) ) ) + { + while ( f_ulSize-- ) + *pbyDst++ = *pbySrc++; + return f_pvDestination; + } + + f_pulAlignedDst = (UINT32 *)pbyDst; + f_pulAlignedSrc = (const UINT32 *)pbySrc; + + /* Copy 4X long words at a time if possible. */ + while ( f_ulSize >= 4 * sizeof(UINT32) ) + { + *f_pulAlignedDst++ = *f_pulAlignedSrc++; + *f_pulAlignedDst++ = *f_pulAlignedSrc++; + *f_pulAlignedDst++ = *f_pulAlignedSrc++; + *f_pulAlignedDst++ = *f_pulAlignedSrc++; + f_ulSize -= 4 * sizeof(UINT32); + } + + /* Copy one long word at a time if possible. */ + while ( f_ulSize >= sizeof(UINT32) ) + { + *f_pulAlignedDst++ = *f_pulAlignedSrc++; + f_ulSize -= sizeof(UINT32); + } + + /* Pick up any residual with a byte copier. */ + pbyDst = (CHAR *)f_pulAlignedDst; + pbySrc = (const CHAR *)f_pulAlignedSrc; + while ( f_ulSize-- ) + *pbyDst++ = *pbySrc++; + + return f_pvDestination; +} +#endif + +/**************************************** llm_list section **********************************************/ + diff --git a/xpp/oct612x/apilib/llman/octapi_llman_private.h b/xpp/oct612x/apilib/llman/octapi_llman_private.h new file mode 100644 index 0000000..14a053d --- /dev/null +++ b/xpp/oct612x/apilib/llman/octapi_llman_private.h @@ -0,0 +1,206 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_llman_private.h + +Copyright (c) 2001 Octasic Inc. All rights reserved. + +Description: + + Library used to manage allocation tables and linked lists. The library is + made such that only a block of contiguous memory is needed for the + management of the linked list/allocation table. + + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 13 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#ifndef __OCTAPI_LLMAN_PRIVATE_H__ +#define __OCTAPI_LLMAN_PRIVATE_H__ + +#include "octdef.h" + + +/**************************************** llm_alloc section **********************************************/ + + +/* Most basic linked list model. + LLM_STR contains a list of "number_of_items" that + are each "unassigned" or "assigned". When requesting + a new element, llm_alloc must choose an "unassigned" + element. An element that is deallocated will be last + to be allocated. +*/ + +typedef struct _LLM_ALLOC +{ + UINT32 *linked_list; /* Each item is either used (0xFFFFFFFE)*/ + /* or unused (pointer to next unused item, 0xFFFFFFFF means last item reached).*/ + UINT32 next_avail_num; /* Points to the next available item in linked list. (0xFFFFFFFF means none available)*/ + UINT32 number_of_items; /* Total number of items in linked list.*/ + UINT32 allocated_items; /* Allocated items in linked list.*/ + +} LLM_ALLOC; + +typedef struct _TLLM_ALLOC_NODE_ +{ + UINT32 value; /* Each item is either used (0xFFFFFFFE)*/ + /* or unused (pointer to next unused item, 0xFFFFFFFF means last item reached).*/ + UINT32 timeout[2]; /* Timeout value that must be exceeded for the node to be considered free again.*/ + +} TLLM_ALLOC_NODE; + + +typedef struct _TLLM_ALLOC_ +{ + TLLM_ALLOC_NODE *linked_list; /* List of nodes used by the link list.*/ + + UINT32 next_avail_num; /* Points to the next available item in linked list. (0xFFFFFFFF means none available)*/ + UINT32 number_of_items; /* Total number of items in linked list.*/ + UINT32 allocated_items; /* Allocated items in linked list.*/ + + UINT32 number_of_timeout; /* Number of block currently in timeout.*/ + UINT32 next_timeout_num; /* Points to the next block currently in timeout.*/ + UINT32 last_timeout_num; /* Last node of the timeout list.*/ + + UINT32 last_known_time[2]; /* last known time.*/ + +} TLLM_ALLOC; + +/* +void octapi_llm_alloc_build_structure(void *l, LLM_ALLOC ** ls); +*/ +/**************************************** llm_alloc section **********************************************/ + + + +/**************************************** llm_list section **********************************************/ +/* This section contains memory structures and functions used + to maintain a variable number of lists (FIFOs) that each + have a variable amount of items. A total amount of items + can be assigned through-out all the lists. Each item in + each list contains a UINT32 specified by the software using + the lists. Each used item in the list is accessible through + it's position in the list. */ + +typedef struct _LLM_LIST_HEAD +{ + UINT32 list_length; /* Current number of items in the list.*/ + /* 0xFFFFFFFF means that the list is not used.*/ + UINT32 head_pointer; /* Number of the item in the item pool that is the first of this list.*/ + /* 0xFFFFFFFF indicates end-of-list link.*/ + UINT32 tail_pointer; /* Number of the item in the item pool that is the last of this list.*/ + + /* Item cache (pointer within the list of the last accessed item):*/ + UINT32 cache_item_number; /* Number of the last accessed item in the list. 0xFFFFFFFF indicates invalid cache.*/ + UINT32 cache_item_pointer; /* Number of the last accessed item in the item pool.*/ +} LLM_LIST_HEAD; + +typedef struct _LLM_LIST_ITEM +{ + UINT32 forward_link; /* Number of the item in the item pool that is next in this list.*/ + /* 0xFFFFFFFF indicates end-of-list link.*/ + + /* User item info (variable size)*/ + UINT32 user_info[1]; +} LLM_LIST_ITEM; + +typedef struct _LLM_LIST +{ + UINT32 user_info_bytes; /* In bytes, size of the user info in a single item.*/ + UINT32 user_info_size; /* In bytes, size of the user info in a single item.*/ + UINT32 item_size; + + UINT32 head_alloc_size; + UINT32 total_items; + UINT32 assigned_items; + + UINT32 total_lists; + UINT32 assigned_lists; + + UINT32 next_empty_item; /* Contains a pointer to the next empty item in the*/ + /* item pool.*/ + + /* Table of all the possible list heads:*/ + LLM_LIST_HEAD * lh; + void * list_head_alloc; /* LLM_ALLOC structure used for list head allocation!*/ + + /* Table of the list items:*/ + LLM_LIST_ITEM * li; +} LLM_LIST; + + +/**********************************************************************************/ +/* These structures are are used by the Llm2 functions to creates lists of ordered + items based on a key given by the user when a new node is inserted in a list. */ +typedef struct _LLM2_LIST_HEAD +{ + UINT32 list_length; /* Current number of items in the list.*/ + /* 0xFFFFFFFF means that the list is not used.*/ + UINT32 head_pointer; /* Number of the item in the item pool that is the first of this list.*/ + /* 0xFFFFFFFF indicates end-of-list link.*/ + UINT32 tail_pointer; /* Number of the item in the item pool that is the last of this list.*/ + +} LLM2_LIST_HEAD; + +typedef struct _LLM2_LIST_ITEM +{ + UINT32 forward_link; /* Number of the item in the item pool that is next in this list.*/ + /* 0xFFFFFFFF indicates end-of-list link.*/ + UINT32 key; /* Key used to order the entries.*/ + + /* User item info (variable size)*/ + UINT32 user_info[1]; +} LLM2_LIST_ITEM; + +typedef struct _LLM2_LIST +{ + UINT32 user_info_bytes; /* In bytes, size of the user info in a single item.*/ + UINT32 user_info_size; /* In bytes, size of the user info in a single item.*/ + UINT32 item_size; + + UINT32 head_alloc_size; + UINT32 total_items; + UINT32 assigned_items; + + UINT32 total_lists; + UINT32 assigned_lists; + + UINT32 next_empty_item; /* Contains a pointer to the next empty item in the*/ + /* item pool.*/ + + /* Table of all the possible list heads:*/ + LLM2_LIST_HEAD * lh; + void * list_head_alloc; /* LLM_ALLOC structure used for list head allocation!*/ + + /* Table of the list items:*/ + LLM2_LIST_ITEM * li; +} LLM2_LIST; + +/*void octapi_llm_list_build_structure(void *l, LLM_LIST ** ls);*/ +LLM_LIST_ITEM * OctApiLlmListGetItemPointer( LLM_LIST * ls, UINT32 item_number ); +LLM2_LIST_ITEM * OctApiLlm2ListGetItemPointer( LLM2_LIST * ls, UINT32 item_number ); +UINT32 OctApiTllmCheckTimeoutList( TLLM_ALLOC *ls, UINT32 current_time[2] ); +VOID * OctApiLlmMemCpy( VOID *f_pvDestination, const VOID * f_pvSource, UINT32 f_ulSize ); +/**************************************** llm_list section **********************************************/ + + + + + +#endif /*__OCTAPI_LLMAN_PRIVATE_H__*/ diff --git a/xpp/oct612x/get_discards b/xpp/oct612x/get_discards new file mode 100755 index 0000000..5436118 --- /dev/null +++ b/xpp/oct612x/get_discards @@ -0,0 +1,51 @@ +#!/usr/bin/php + + diff --git a/xpp/oct612x/include/apilib/octapi_bt0.h b/xpp/oct612x/include/apilib/octapi_bt0.h new file mode 100644 index 0000000..a0f22ca --- /dev/null +++ b/xpp/oct612x/include/apilib/octapi_bt0.h @@ -0,0 +1,75 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_bt0.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Library used to manage a binary tree of variable max size. Library is + made to use one block of contiguous memory to manage the tree. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 11 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#ifndef __OCTAPI_BT0_H__ +#define __OCTAPI_BT0_H__ + +#include "octdef.h" + +#define OCTAPI_BT0_BASE 0xFFFF0000 +#define OCTAPI_BT0_KEY_SIZE_NOT_MUTLIPLE_OF_UINT32 OCTAPI_BT0_BASE+0x0001 +#define OCTAPI_BT0_DATA_SIZE_NOT_MUTLIPLE_OF_UINT32 OCTAPI_BT0_BASE+0x0002 +#define OCTAPI_BT0_MALLOC_FAILED OCTAPI_BT0_BASE+0x0003 +#define OCTAPI_BT0_NO_NODES_AVAILABLE OCTAPI_BT0_BASE+0x0004 +#define OCTAPI_BT0_KEY_ALREADY_IN_TREE OCTAPI_BT0_BASE+0x0005 +#define OCTAPI_BT0_KEY_NOT_IN_TREE OCTAPI_BT0_BASE+0x0006 + +/* Possible result for Find Or Add function. */ +#define OCTAPI0_BT0_NODE_FOUND 0 +#define OCTAPI0_BT0_NODE_ADDDED 1 + +#define OCTAPI_BT0_NO_SMALLER_KEY 0xAAAAAAAA + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define octapi_bt0_get_size( number_of_items, key_size, data_size, b_size ) OctApiBt0GetSize( (UINT32) number_of_items,(UINT32) key_size, (UINT32) data_size, (PUINT32) b_size ) +#define octapi_bt0_init( b, number_of_items, key_size, data_size ) OctApiBt0Init( (void **) b,(UINT32) number_of_items,(UINT32) key_size, (UINT32) data_size ) +#define octapi_bt0_add_node( b, key, data ) OctApiBt0AddNode( (void *) b,(void *) key,(void **) data ) +#define octapi_bt0_remove_node( b, key ) OctApiBt0RemoveNode( (void *) b,(void *) key ) +#define octapi_bt0_query_node( b, key, data ) OctApiBt0QueryNode( (void *) b,(void *) key,(void **) data ) +#define octapi_bt0_get_first_node( b, key, data ) OctApiBt0GetFirstNode( (void *) b,(void **) key, (void **) data ) + +UINT32 OctApiBt0GetSize( UINT32 number_of_items, UINT32 key_size, UINT32 data_size, UINT32 * b_size ); +UINT32 OctApiBt0Init( void ** b, UINT32 number_of_items, UINT32 key_size, UINT32 data_size ); +UINT32 OctApiBt0AddNode( void * b, void * key, void ** data ); +UINT32 OctApiBt0RemoveNode( void * b, void * key ); +UINT32 OctApiBt0QueryNode( void * b, void * key, void ** data ); +UINT32 OctApiBt0GetFirstNode( void * b, void ** key, void ** data ); +UINT32 OctApiBt0FindOrAddNode( void * b, void * key, void ** data, UINT32 *fnct_result ); + +UINT32 OctApiBt0AddNodeReportPrevNodeData( void * b, void * key, void ** data, void ** prev_data, UINT32 *fnct_result ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /*__OCTAPI_BT0_H__*/ diff --git a/xpp/oct612x/include/apilib/octapi_largmath.h b/xpp/oct612x/include/apilib/octapi_largmath.h new file mode 100644 index 0000000..1680474 --- /dev/null +++ b/xpp/oct612x/include/apilib/octapi_largmath.h @@ -0,0 +1,69 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_largmath.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Library used to perform arithmetic on integer values of an integer multiple + of 32-bits. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 6 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#ifndef __OCTAPI_LARGMATH_H__ +#define __OCTAPI_LARGMATH_H__ + +#include "octdef.h" + +#define OCTAPI_LM_DIVISION_BY_ZERO 0xFFFF +#define OCTAPI_LM_OVERFLOW 0xFFFE +#define OCTAPI_LM_ARRAY_SIZE_MISMATCH 0xFFFD + +#define OCTAPI_LM_MAX_OPTIMIZE_MUL 10 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define octapi_lm_add( a, alen, b, blen, z, zlen ) OctApiLmAdd( (PUINT32) a, (USHORT) alen, (PUINT32) b, (USHORT) blen, (PUINT32) z, (USHORT) zlen ) +#define octapi_lm_subtract( a, alen, bneg, blen, z, zlen, neg ) OctApiLmSubtract( (PUINT32) a, (USHORT) alen, (PUINT32) bneg, (USHORT) blen, (PUINT32) z, (USHORT) zlen, (USHORT*) neg ) +#define octapi_lm_compare( a, alen, bneg, blen, neg ) OctApiLmCompare( (PUINT32) a, (USHORT) alen, (PUINT32) bneg, (USHORT) blen, (USHORT*) neg ) +#define octapi_lm_multiply( a, b, ablen, z ) OctApiLmMultiply( (PUINT32) a, (PUINT32) b, (USHORT) ablen, (PUINT32) z ) +#define octapi_lm_divide( n, d, q, r, ndqrlen ) OctApiLmDivide( (PUINT32) n, (PUINT32) d, (PUINT32) q, (PUINT32) r, (USHORT) ndqrlen ) +#define octapi_lm_shiftright1( a, alen ) OctApiLmShiftRight1( (PUINT32) a, (USHORT) alen ) +#define octapi_lm_shiftn( a, alen, shiftleft, shiftn ) OctApiLmShiftn( (PUINT32) a, (USHORT) alen, (USHORT) shiftleft, (USHORT) shiftn ) +#define octapi_lm_getmsb( a, alen, msb_pos ) OctApiLmGetMsb( (PUINT32) a, (USHORT) alen, (USHORT*) msb_pos ) + + +UINT32 OctApiLmAdd( PUINT32 a, USHORT alen, PUINT32 b, USHORT blen, PUINT32 z, USHORT zlen ); +UINT32 OctApiLmSubtract( PUINT32 a, USHORT alen, PUINT32 bneg, USHORT blen, PUINT32 z, USHORT zlen, PUSHORT neg ); +UINT32 OctApiLmCompare( PUINT32 a, USHORT alen, PUINT32 bneg, USHORT blen, PUSHORT neg ); +UINT32 OctApiLmMultiply( PUINT32 a, PUINT32 b, USHORT ablen, PUINT32 z ); +UINT32 OctApiLmDivide( PUINT32 n, PUINT32 d, PUINT32 q, PUINT32 r, USHORT ndqrlen ); +UINT32 OctApiLmShiftRight1( PUINT32 a, USHORT alen ); +UINT32 OctApiLmShiftn( PUINT32 a, USHORT alen, USHORT shiftleft, USHORT shiftn ); +UINT32 OctApiLmGetMsb( PUINT32 a, USHORT alen, PUSHORT msb_pos ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __OCTAPI_LARGMATH_H__ */ diff --git a/xpp/oct612x/include/apilib/octapi_llman.h b/xpp/oct612x/include/apilib/octapi_llman.h new file mode 100644 index 0000000..b70a851 --- /dev/null +++ b/xpp/oct612x/include/apilib/octapi_llman.h @@ -0,0 +1,142 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_llman.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Library used to manage allocation tables and linked lists. The library is + made such that only a block of contiguous memory is needed for the + management of the linked list/allocation table. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 8 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#ifndef __OCTAPI_LLMAN_H__ +#define __OCTAPI_LLMAN_H__ + +#include "octdef.h" + +/* Error defines. */ +#define OCTAPI_LLM_MEMORY_NOT_ALLOCATED 0xFFFFFFFF +#define OCTAPI_LLM_NO_STRUCTURES_LEFT 0xFFFFFFFE +#define OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE 0xFFFFFFFD +#define OCTAPI_LLM_ELEMENT_ALREADY_ASSIGNED 0xFFFFFFFC +#define OCTAPI_LLM_ELEMENT_NOT_FOUND 0xFFFFFFFB +#define OCTAPI_LLM_LIST_EMPTY 0xFFFFFFFA +#define OCTAPI_LLM_INVALID_LIST_HANDLE 0xFFFFFFF9 +#define OCTAPI_LLM_TREE_NODE_ABSENT 0xFFFFFFF8 +#define OCTAPI_LLM_INTERNAL_ERROR0 0xFFFFFFF7 +#define OCTAPI_LLM_INTERNAL_ERROR1 0xFFFFFFF6 +#define OCTAPI_LLM_INVALID_PARAMETER 0xFFFFFFF5 + +#define OCTAPI_LLM2_MEMORY_NOT_ALLOCATED 0xFEFFFFFF +#define OCTAPI_LLM2_NO_STRUCTURES_LEFT 0xFEFFFFFE +#define OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE 0xFEFFFFFD +#define OCTAPI_LLM2_ELEMENT_ALREADY_ASSIGNED 0xFEFFFFFC +#define OCTAPI_LLM2_ELEMENT_NOT_FOUND 0xFEFFFFFB +#define OCTAPI_LLM2_LIST_EMPTY 0xFEFFFFFA +#define OCTAPI_LLM2_INVALID_LIST_HANDLE 0xFEFFFFF9 +#define OCTAPI_LLM2_TREE_NODE_ABSENT 0xFEFFFFF8 +#define OCTAPI_LLM2_INTERNAL_ERROR0 0xFEFFFFF7 +#define OCTAPI_LLM2_INTERNAL_ERROR1 0xFEFFFFF6 +#define OCTAPI_LLM2_INVALID_PARAMETER 0xFEFFFFF5 + +/* Other defines. */ +#define OCTAPI_LLM_LIST_APPEND 0xFFFFFFFF +#define OCTAPI_LLM2_INSERT_ERROR 0xFFFFFFFF +#define OCTAPI_LLM2_INSERT_FIRST_NODE 0xFFFF0000 +#define OCTAPI_LLM2_INSERT_LIST_NODE 0xFFFF0001 +#define OCTAPI_LLM2_INSERT_LAST_NODE 0xFFFF0002 +#define OCTAPI_LLM2_INSERT_BEFORE_LAST_NODE 0xFFFF0003 +#define OCTAPI_LLM2_REMOVE_ERROR 0xFFFFFFFF +#define OCTAPI_LLM2_REMOVE_FIRST_NODE 0xFFFF0004 +#define OCTAPI_LLM2_REMOVE_LIST_NODE 0xFFFF0005 +#define OCTAPI_LLM2_REMOVE_LAST_NODE 0xFFFF0006 +#define OCTAPI_LLM2_REMOVE_BEFORE_LAST_NODE 0xFFFF0007 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define octapi_llm_alloc_get_size( number_of_items, l_size ) OctapiLlmAllocGetSize( (UINT32) number_of_items,(PUINT32) l_size ) +#define octapi_llm_alloc_init( l, number_of_items ) OctapiLlmAllocInit( (PVOID*) l,(UINT32) number_of_items ) +#define octapi_llm_alloc_info( l, allocated_items, available_items ) OctapiLlmAllocInfo( (PVOID) l, (PUINT32) allocated_items, (PUINT32) available_items ) +#define octapi_llm_alloc_alloc( l, blocknum ) OctapiLlmAllocAlloc( (PVOID) l, (PUINT32) blocknum ) +#define octapi_llm_alloc_dealloc( l, blocknum ) OctapiLlmAllocDealloc( (PVOID) l,(UINT32) blocknum ) +#define octapi_llm_list_get_size( number_of_items, number_of_lists, user_info_size, l_size ) OctApiLlmListGetSize( (UINT32) number_of_items,(UINT32) number_of_lists,(UINT32) user_info_size,(PUINT32) l_size ) +#define octapi_llm_list_init( l, number_of_items, number_of_lists, user_info_size ) OctApiLlmListInit( (PVOID*) l,(UINT32) number_of_items,(UINT32) number_of_lists,(UINT32) user_info_size ) +#define octapi_llm_list_info( l, allocated_lists, allocated_items, free_lists, free_items ) OctApiLlmListInfo( (PVOID) l,(PUINT32) allocated_lists,(PUINT32) allocated_items,(PUINT32) free_lists,(PUINT32) free_items ) +#define octapi_llm_list_create( l, list_handle ) OctApiLlmListCreate( (PVOID) l,(PUINT32) list_handle ) +#define octapi_llm_list_create_full( l, list_length, plist_handle ) OctApiLlmListCreateFull( (PVOID) l, (UINT32) list_length, (PUINT32) plist_handle ) +#define octapi_llm_list_append_items( l, list_handle, num_items ) OctApiLlmListAppendItems( (PVOID) l, (UINT32) list_handle, (UINT32) num_items ) +#define octapi_llm_list_append_and_set_items( l, list_handle, num_items, data_list ) OctApiLlmListAppendAndSetItems( (PVOID) l, (UINT32) list_handle, (UINT32) num_items, (PVOID) data_list ) +#define octapi_llm_list_delete( l, list_handle ) OctApiLlmListDelete( (PVOID) l,(UINT32) list_handle ) +#define octapi_llm_list_length( l, list_handle, number_of_items_in_list ) OctApiLlmListLength( (PVOID) l,(UINT32) list_handle, (PUINT32) number_of_items_in_list ) +#define octapi_llm_list_insert_item( l, list_handle, item_number, item_data_pnt ) OctApiLlmListInsertItem( (PVOID) l,(UINT32) list_handle,(UINT32) item_number,(PVOID*) item_data_pnt ) +#define octapi_llm_list_remove_item( l, list_handle, item_number ) OctApiLlmListRemoveItem( (PVOID) l,(UINT32) list_handle,(UINT32) item_number ) +#define octapi_llm_list_item_data( l, list_handle, item_number, item_data_pnt ) OctApiLlmListItemData( (PVOID) l,(UINT32) list_handle,(UINT32) item_number,(PVOID*) item_data_pnt ) +#define octapi_llm_list_copy_data( l, list_handle, start_item, data_length, pdata_list ) OctApiLlmListCopyData( (PVOID) l, (UINT32) list_handle, (UINT32) start_item, (UINT32) data_length, (PVOID) pdata_list ) +#define octapi_llm_list_set_items( l, list_handle, start_item, data_length, pdata_list ) OctApiLlmListSetItems( (PVOID) l, (UINT32) list_handle, (UINT32) start_item, (UINT32) data_length, (PVOID) pdata_list ) + +/* Alloc man. */ +UINT32 OctapiLlmAllocGetSize( UINT32 number_of_items,PUINT32 l_size ); +UINT32 OctapiLlmAllocInit( PVOID* l,UINT32 number_of_items ); +UINT32 OctapiLlmAllocInfo( PVOID l, PUINT32 allocated_items, PUINT32 available_items ); +UINT32 OctapiLlmAllocAlloc( PVOID l, PUINT32 blocknum ); +UINT32 OctapiLlmAllocDealloc( PVOID l,UINT32 blocknum ); + +/* Time managed alloc man. */ +UINT32 OctApiTllmAllocGetSize( UINT32 number_of_items, PUINT32 l_size ); +UINT32 OctApiTllmAllocInit( PVOID* l, UINT32 number_of_items ); +UINT32 OctApiTllmAllocInfo( PVOID l, PUINT32 allocated_items, PUINT32 available_items ); +UINT32 OctApiTllmAllocAlloc( PVOID l, PUINT32 blocknum, UINT32 current_time[2] ); +UINT32 OctApiTllmAllocDealloc( PVOID l, UINT32 blocknum, UINT32 timeout_value, UINT32 current_time[2] ); + +/* List man. */ +UINT32 OctApiLlmListGetSize( UINT32 number_of_items, UINT32 number_of_lists, UINT32 user_info_size, PUINT32 l_size ); +UINT32 OctApiLlmListInit( PVOID* l, UINT32 number_of_items, UINT32 number_of_lists, UINT32 user_info_size ); +UINT32 OctApiLlmListInfo( PVOID l, PUINT32 allocated_lists, PUINT32 allocated_items, PUINT32 free_lists, PUINT32 free_items ); +UINT32 OctApiLlmListCreate( PVOID l, PUINT32 list_handle ); +UINT32 OctApiLlmListCreateFull( PVOID l, UINT32 list_length, UINT32* plist_handle ); +UINT32 OctApiLlmListAppendItems( PVOID l, UINT32 list_handle, UINT32 num_items ); +UINT32 OctApiLlmListAppendAndSetItems( PVOID l, UINT32 list_handle, UINT32 num_items, PVOID data_list ); +UINT32 OctApiLlmListDelete( PVOID l, UINT32 list_handle ); +UINT32 OctApiLlmListLength( PVOID l, UINT32 list_handle, PUINT32 number_of_items_in_list ); +UINT32 OctApiLlmListInsertItem( PVOID l, UINT32 list_handle, UINT32 item_number, PVOID* item_data_pnt ); +UINT32 OctApiLlmListRemoveItem( PVOID l, UINT32 list_handle, UINT32 item_number ); +UINT32 OctApiLlmListItemData( PVOID l, UINT32 list_handle, UINT32 item_number, PVOID* item_data_pnt ); +UINT32 OctApiLlmListCopyData( PVOID l, UINT32 list_handle, UINT32 start_item, UINT32 data_length, PVOID pdata_list ); +UINT32 OctApiLlmListSetItems( PVOID l, UINT32 list_handle, UINT32 start_item, UINT32 data_length, PVOID pdata_list ); + +/* Second list manager using a key to order info in the list. */ +UINT32 OctApiLlm2ListGetSize( UINT32 number_of_items, UINT32 number_of_lists, UINT32 user_info_size, PUINT32 l_size ); +UINT32 OctApiLlm2ListInit( PVOID* l,UINT32 number_of_items, UINT32 number_of_lists, UINT32 user_info_size ); +UINT32 OctApiLlm2ListCreate( PVOID l, PUINT32 list_handle ); +UINT32 OctApiLlm2ListLength( PVOID l, UINT32 list_handle, PUINT32 number_of_items_in_list ); +UINT32 OctApiLlm2ListInsertItem(void * l, UINT32 list_handle, UINT32 item_key, void ** item_data_pnt, void ** prev_item_data_pnt, void ** prev_prev_item_data_pnt, PUINT32 insert_status_pnt ); +UINT32 OctApiLlm2ListRemoveItem(void * l, UINT32 list_handle, UINT32 item_key, PUINT32 prev_item_key_pnt, PUINT32 prev_prev_item_key_pnt, PUINT32 remove_status_pnt ); +UINT32 OctApiLlm2ListItemData( PVOID l, UINT32 list_handle, UINT32 item_key, PVOID* item_data_pnt, PUINT32 item_number ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __OCTAPI_LLMAN_H__ */ diff --git a/xpp/oct612x/include/digium_unused.h b/xpp/oct612x/include/digium_unused.h new file mode 100644 index 0000000..ecf382f --- /dev/null +++ b/xpp/oct612x/include/digium_unused.h @@ -0,0 +1,297 @@ +/* Define macros here to suppress functions from the API being built */ + +#if 1 + +#define SKIP_Oct6100AdpcmChanOpenDef 1 +#define SKIP_Oct6100AdpcmChanOpen 1 +#define SKIP_Oct6100AdpcmChanCloseDef 1 +#define SKIP_Oct6100AdpcmChanClose 1 +#define SKIP_Oct6100AdpcmChanOpenSer 1 +#define SKIP_Oct6100ApiCheckAdpcmChanParams 1 +#define SKIP_Oct6100ApiReserveAdpcmChanResources 1 +#define SKIP_Oct6100ApiWriteAdpcmChanStructs 1 +#define SKIP_Oct6100ApiUpdateAdpcmChanEntry 1 +#define SKIP_Oct6100AdpcmChanCloseSer 1 +#define SKIP_Oct6100ApiAssertAdpcmChanParams 1 +#define SKIP_Oct6100ApiInvalidateAdpcmChanStructs 1 +#define SKIP_Oct6100ApiReleaseAdpcmChanResources 1 +#define SKIP_Oct6100ApiReserveAdpcmChanEntry 1 +#define SKIP_Oct6100ApiReleaseAdpcmChanEntry 1 +#define SKIP_Oct6100ChannelCloseDef 1 +#define SKIP_Oct6100ChannelClose 1 +#define SKIP_Oct6100ChannelCreateBiDirDef 1 +#define SKIP_Oct6100ChannelCreateBiDir 1 +#define SKIP_Oct6100ChannelDestroyBiDirDef 1 +#define SKIP_Oct6100ChannelDestroyBiDir 1 +#define SKIP_Oct6100ChannelBroadcastTsstAddDef 1 +#define SKIP_Oct6100ChannelBroadcastTsstAdd 1 +#define SKIP_Oct6100ChannelBroadcastTsstRemove 1 +#define SKIP_Oct6100ChannelGetStatsDef 1 +#define SKIP_Oct6100ChannelGetStats 1 +#define SKIP_Oct6100ChannelMuteDef 1 +#define SKIP_Oct6100ChannelMute 1 +#define SKIP_Oct6100ChannelUnMuteDef 1 +#define SKIP_Oct6100ChannelUnMute 1 +#define SKIP_Oct6100ChannelCloseSer 1 +#define SKIP_Oct6100ApiAssertChannelParams 1 +#define SKIP_Oct6100ApiInvalidateChannelStructs 1 +#define SKIP_Oct6100ApiReleaseChannelResources 1 +#define SKIP_Oct6100ChannelBroadcastTsstAddSer 1 +#define SKIP_Oct6100ApiCheckChanTsstAddParams 1 +#define SKIP_Oct6100ApiReserveTsstAddResources 1 +#define SKIP_Oct6100ApiWriteTsstAddStructs 1 +#define SKIP_Oct6100ApiUpdateTsstAddChanEntry 1 +#define SKIP_Oct6100ApiChannelGetStatsSer 1 +#define SKIP_Oct6100ApiReserveBiDirChanEntry 1 +#define SKIP_Oct6100ApiReleaseBiDirChanEntry 1 +#define SKIP_Oct6100ApiRetrieveNlpConfDword 1 +#define SKIP_Oct6100ApiSaveNlpConfDword 1 +#define SKIP_Oct6100ChannelCreateBiDirSer 1 +#define SKIP_Oct6100ApiCheckChannelCreateBiDirParams 1 +#define SKIP_Oct6100ApiReserveChannelCreateBiDirResources 1 +#define SKIP_Oct6100ApiWriteChannelCreateBiDirStructs 1 +#define SKIP_Oct6100ApiUpdateBiDirChannelEntry 1 +#define SKIP_Oct6100ChannelDestroyBiDirSer 1 +#define SKIP_Oct6100ApiAssertDestroyBiDirChanParams 1 +#define SKIP_Oct6100ApiInvalidateBiDirChannelStructs 1 +#define SKIP_Oct6100ApiReleaseBiDirChannelResources 1 +#define SKIP_Oct6100ApiOctFloatToDbEnergyByte 1 +#define SKIP_Oct6100ApiOctFloatToDbEnergyHalf 1 +#define SKIP_Oct6100ChannelMuteSer 1 +#define SKIP_Oct6100ApiAssertChannelMuteParams 1 +#define SKIP_Oct6100ChannelUnMuteSer 1 +#define SKIP_Oct6100ApiAssertChannelUnMuteParams 1 +#define SKIP_Oct6100ApiMuteSinWithFeatures 1 +#define SKIP_Oct6100ApiMuteChannelPorts 1 +#define SKIP_Oct6100CreateLocalInstanceDef 1 +#define SKIP_Oct6100CreateLocalInstance 1 +#define SKIP_Oct6100DestroyLocalInstanceDef 1 +#define SKIP_Oct6100DestroyLocalInstance 1 +#define SKIP_Oct6100GetHwRevisionDef 1 +#define SKIP_Oct6100GetHwRevision 1 +#define SKIP_Oct6100FreeResourcesDef 1 +#define SKIP_Oct6100FreeResources 1 +#define SKIP_Oct6100ProductionBistDef 1 +#define SKIP_Oct6100ProductionBist 1 +#define SKIP_Oct6100ApiGetVersionDef 1 +#define SKIP_Oct6100ApiGetVersion 1 +#define SKIP_Oct6100FreeResourcesSer 1 +#define SKIP_Oct6100ProductionBistSer 1 +#define SKIP_Oct6100ChipGetStatsDef 1 +#define SKIP_Oct6100ChipGetStats 1 +#define SKIP_Oct6100ChipGetImageInfoDef 1 +#define SKIP_Oct6100ChipGetImageInfo 1 +#define SKIP_Oct6100ChipGetStatsSer 1 +#define SKIP_Oct6100ConfBridgeOpenDef 1 +#define SKIP_Oct6100ConfBridgeOpen 1 +#define SKIP_Oct6100ConfBridgeClose 1 +#define SKIP_Oct6100ConfBridgeChanAddDef 1 +#define SKIP_Oct6100ConfBridgeChanAdd 1 +#define SKIP_Oct6100ConfBridgeChanRemove 1 +#define SKIP_Oct6100ConfBridgeChanMuteDef 1 +#define SKIP_Oct6100ConfBridgeChanMute 1 +#define SKIP_Oct6100ConfBridgeChanUnMuteDef 1 +#define SKIP_Oct6100ConfBridgeChanUnMute 1 +#define SKIP_Oct6100ConfBridgeDominantSpeakerSetDef 1 +#define SKIP_Oct6100ConfBridgeDominantSpeakerSet 1 +#define SKIP_Oct6100ConfBridgeMaskChangeDef 1 +#define SKIP_Oct6100ConfBridgeMaskChange 1 +#define SKIP_Oct6100ConfBridgeGetStatsDef 1 +#define SKIP_Oct6100ConfBridgeGetStats 1 +#define SKIP_Oct6100ConfBridgeOpenSer 1 +#define SKIP_Oct6100ApiCheckBridgeParams 1 +#define SKIP_Oct6100ApiReserveBridgeResources 1 +#define SKIP_Oct6100ApiUpdateBridgeEntry 1 +#define SKIP_Oct6100ConfBridgeChanAddSer 1 +#define SKIP_Oct6100ApiCheckBridgeAddParams 1 +#define SKIP_Oct6100ApiReserveBridgeAddResources 1 +#define SKIP_Oct6100ApiBridgeEventAdd 1 +#define SKIP_Oct6100ApiBridgeAddParticipantToChannel 1 +#define SKIP_Oct6100ConfBridgeChanMuteSer 1 +#define SKIP_Oct6100ApiCheckBridgeMuteParams 1 +#define SKIP_Oct6100ApiUpdateBridgeMuteResources 1 +#define SKIP_Oct6100ConfBridgeChanUnMuteSer 1 +#define SKIP_Oct6100ApiCheckBridgeUnMuteParams 1 +#define SKIP_Oct6100ApiUpdateBridgeUnMuteResources 1 +#define SKIP_Oct6100ConfBridgeDominantSpeakerSetSer 1 +#define SKIP_Oct6100ApiCheckBridgeDominantSpeakerParams 1 +#define SKIP_Oct6100ApiUpdateBridgeDominantSpeakerResources 1 +#define SKIP_Oct6100ConfBridgeMaskChangeSer 1 +#define SKIP_Oct6100ApiCheckBridgeMaskChangeParams 1 +#define SKIP_Oct6100ApiUpdateMaskModifyResources 1 +#define SKIP_Oct6100ApiBridgeUpdateMask 1 +#define SKIP_Oct6100ConfBridgeGetStatsSer 1 +#define SKIP_Oct6100ApiReserveBridgeEntry 1 +#define SKIP_Oct6100ApiReserveFlexConfParticipantEntry 1 +#define SKIP_Oct6100DebugSelectChannelDef 1 +#define SKIP_Oct6100DebugSelectChannel 1 +#define SKIP_Oct6100DebugGetDataDef 1 +#define SKIP_Oct6100DebugGetData 1 +#define SKIP_Oct6100DebugSelectChannelSer 1 +#define SKIP_Oct6100DebugGetDataSer 1 +#define SKIP_Oct6100BufferPlayoutGetEventDef 1 +#define SKIP_Oct6100BufferPlayoutGetEvent 1 +#define SKIP_Oct6100BufferPlayoutGetEventSer 1 +#define SKIP_Oct6100InterruptConfigureDef 1 +#define SKIP_Oct6100InterruptConfigure 1 +#define SKIP_Oct6100ApiReserveBufferPlayoutMemoryNode 1 +#define SKIP_Oct6100ApiReleaseBufferPlayoutMemoryNode 1 +#define SKIP_Oct6100ApiReserveBufferPlayoutMemory 1 +#define SKIP_Oct6100ApiReleaseBufferPlayoutMemory 1 +#define SKIP_Oct6100ApiCreateFeatureMask 1 +#define SKIP_Oct6100MixerCopyEventCreateDef 1 +#define SKIP_Oct6100MixerCopyEventCreate 1 +#define SKIP_Oct6100MixerCopyEventDestroyDef 1 +#define SKIP_Oct6100MixerCopyEventDestroy 1 +#define SKIP_Oct6100MixerCopyEventCreateSer 1 +#define SKIP_Oct6100ApiCheckCopyEventCreateParams 1 +#define SKIP_Oct6100ApiReserveCopyEventCreateResources 1 +#define SKIP_Oct6100ApiWriteCopyEventCreateStructs 1 +#define SKIP_Oct6100ApiUpdateCopyEventCreateEntry 1 +#define SKIP_Oct6100MixerCopyEventDestroySer 1 +#define SKIP_Oct6100ApiAssertCopyEventDestroyParams 1 +#define SKIP_Oct6100ApiInvalidateCopyEventStructs 1 +#define SKIP_Oct6100ApiReleaseCopyEventResources 1 +#define SKIP_Oct6100ApiReserveCopyEventEntry 1 +#define SKIP_Oct6100ApiReleaseCopyEventEntry 1 +#define SKIP_Oct6100PhasingTsstOpenDef 1 +#define SKIP_Oct6100PhasingTsstOpen 1 +#define SKIP_Oct6100PhasingTsstCloseDef 1 +#define SKIP_Oct6100PhasingTsstClose 1 +#define SKIP_Oct6100PhasingTsstOpenSer 1 +#define SKIP_Oct6100ApiCheckPhasingParams 1 +#define SKIP_Oct6100ApiReservePhasingResources 1 +#define SKIP_Oct6100ApiWritePhasingStructs 1 +#define SKIP_Oct6100ApiUpdatePhasingEntry 1 +#define SKIP_Oct6100PhasingTsstCloseSer 1 +#define SKIP_Oct6100ApiAssertPhasingParams 1 +#define SKIP_Oct6100ApiInvalidatePhasingStructs 1 +#define SKIP_Oct6100ApiReleasePhasingResources 1 +#define SKIP_Oct6100ApiReservePhasingEntry 1 +#define SKIP_Oct6100ApiReleasePhasingEntry 1 +#define SKIP_Oct6100BufferPlayoutLoadDef 1 +#define SKIP_Oct6100BufferPlayoutLoad 1 +#define SKIP_Oct6100BufferPlayoutLoadBlockInitDef 1 +#define SKIP_Oct6100BufferPlayoutLoadBlockInit 1 +#define SKIP_Oct6100BufferPlayoutLoadBlockDef 1 +#define SKIP_Oct6100BufferPlayoutLoadBlock 1 +#define SKIP_Oct6100BufferPlayoutUnloadDef 1 +#define SKIP_Oct6100BufferPlayoutUnload 1 +#define SKIP_Oct6100BufferPlayoutAddDef 1 +#define SKIP_Oct6100BufferPlayoutAdd 1 +#define SKIP_Oct6100BufferPlayoutStartDef 1 +#define SKIP_Oct6100BufferPlayoutStart 1 +#define SKIP_Oct6100BufferPlayoutStop 1 +#define SKIP_Oct6100BufferLoadSer 1 +#define SKIP_Oct6100BufferLoadBlockInitSer 1 +#define SKIP_Oct6100BufferLoadBlockSer 1 +#define SKIP_Oct6100ApiCheckBufferParams 1 +#define SKIP_Oct6100ApiCheckBufferLoadBlockParams 1 +#define SKIP_Oct6100ApiReserveBufferResources 1 +#define SKIP_Oct6100ApiWriteBufferInMemory 1 +#define SKIP_Oct6100ApiUpdateBufferEntry 1 +#define SKIP_Oct6100BufferUnloadSer 1 +#define SKIP_Oct6100ApiAssertBufferParams 1 +#define SKIP_Oct6100ApiReleaseBufferResources 1 +#define SKIP_Oct6100BufferPlayoutAddSer 1 +#define SKIP_Oct6100ApiCheckPlayoutAddParams 1 +#define SKIP_Oct6100ApiWriteBufferAddStructs 1 +#define SKIP_Oct6100BufferPlayoutStartSer 1 +#define SKIP_Oct6100ApiCheckPlayoutStartParams 1 +#define SKIP_Oct6100ApiWriteChanPlayoutStructs 1 +#define SKIP_Oct6100ApiReserveBufPlayoutListEntry 1 +#define SKIP_Oct6100ApiReleaseBufPlayoutListEntry 1 +#define SKIP_Oct6100RemoteDebugDef 1 +#define SKIP_Oct6100RemoteDebug 1 +#define SKIP_Oct6100ApiCheckEndianDetectField 1 +#define SKIP_Oct6100ApiCalculateChecksum 1 +#define SKIP_Oct6100ApiFormResponsePkt 1 +#define SKIP_Oct6100ApiCheckPktCommands 1 +#define SKIP_Oct6100ApiExecutePktCommands 1 +#define SKIP_Oct6100ApiCheckSessionNum 1 +#define SKIP_Oct6100ApiRpcReadWord 1 +#define SKIP_Oct6100ApiRpcReadBurst 1 +#define SKIP_Oct6100ApiRpcReadArray 1 +#define SKIP_Oct6100ApiRpcWriteWord 1 +#define SKIP_Oct6100ApiRpcWriteSmear 1 +#define SKIP_Oct6100ApiRpcWriteBurst 1 +#define SKIP_Oct6100ApiRpcSetHotChannel 1 +#define SKIP_Oct6100ApiRpcGetDebugChanIndex 1 +#define SKIP_Oct6100ApiRpcDisconnect 1 +#define SKIP_Oct6100ToneDetectionDisable 1 +#define SKIP_Oct6100TsiCnctOpenDef 1 +#define SKIP_Oct6100TsiCnctOpen 1 +#define SKIP_Oct6100TsiCnctCloseDef 1 +#define SKIP_Oct6100TsiCnctClose 1 +#define SKIP_Oct6100TsiCnctOpenSer 1 +#define SKIP_Oct6100ApiCheckTsiParams 1 +#define SKIP_Oct6100ApiReserveTsiResources 1 +#define SKIP_Oct6100ApiWriteTsiStructs 1 +#define SKIP_Oct6100ApiUpdateTsiEntry 1 +#define SKIP_Oct6100TsiCnctCloseSer 1 +#define SKIP_Oct6100ApiAssertTsiParams 1 +#define SKIP_Oct6100ApiInvalidateTsiStructs 1 +#define SKIP_Oct6100ApiReleaseTsiResources 1 +#define SKIP_Oct6100ApiReserveTsiCnctEntry 1 +#define SKIP_Oct6100ApiReleaseTsiCnctEntry 1 +#define SKIP_Oct6100UserDriverWriteOs 1 +#define SKIP_Oct6100UserDriverWriteSmearOs 1 +#define SKIP_Oct6100UserDriverWriteBurstOs 1 +#define SKIP_Oct6100UserDriverReadOs 1 +#define SKIP_Oct6100UserDriverReadBurstOs 1 +#define SKIP_OctApiBt0AddNode 1 +#define SKIP_OctApiBt0AddNode2 1 +#define SKIP_OctApiBt0AddNode3 1 +#define SKIP_OctApiBt0AddNode4 1 +#define SKIP_OctApiBt0KeyCompare 1 +#define SKIP_OctApiBt0UpdateLinkDepth 1 +#define SKIP_OctApiBt0Rebalance 1 +#define SKIP_OctApiBt0ExternalHeavy 1 +#define SKIP_OctApiBt0RemoveNode2 1 +#define SKIP_OctApiBt0RemoveNode3 1 +#define SKIP_OctApiBt0RemoveNode 1 +#define SKIP_OctApiBt0QueryNode2 1 +#define SKIP_OctApiBt0QueryNode 1 +#define SKIP_OctApiBt0GetFirstNode 1 +#define SKIP_OctApiBt0FindOrAddNode 1 +#define SKIP_OctApiBt0AddNodeReportPrevNodeData 1 +#define SKIP_OctApiLmCompare 1 +#define SKIP_OctApiLmMultiply 1 +#define SKIP_OctApiLmDivide 1 +#define SKIP_OctApiLmShiftRight1 1 +#define SKIP_OctApiLmShiftn 1 +#define SKIP_OctApiLmGetMsb 1 +#define SKIP_OctApiTllmAllocGetSize 1 +#define SKIP_OctApiTllmAllocInit 1 +#define SKIP_OctApiTllmAllocInfo 1 +#define SKIP_OctApiTllmAllocAlloc 1 +#define SKIP_OctApiTllmAllocDealloc 1 +#define SKIP_OctApiTllmCheckTimeoutList 1 +#define SKIP_OctApiLlmListGetSize 1 +#define SKIP_OctApiLlmListGetItemPointer 1 +#define SKIP_OctApiLlmListInit 1 +#define SKIP_OctApiLlmListInfo 1 +#define SKIP_OctApiLlmListCreate 1 +#define SKIP_OctApiLlmListDelete 1 +#define SKIP_OctApiLlmListLength 1 +#define SKIP_OctApiLlmListItemData 1 +#define SKIP_OctApiLlmListInsertItem 1 +#define SKIP_OctApiLlmListCreateFull 1 +#define SKIP_OctApiLlmListAppendItems 1 +#define SKIP_OctApiLlmListAppendAndSetItems 1 +#define SKIP_OctApiLlmListSetItems 1 +#define SKIP_OctApiLlmListCopyData 1 +#define SKIP_OctApiLlmListRemoveItem 1 +#define SKIP_OctApiLlm2ListGetSize 1 +#define SKIP_OctApiLlm2ListGetItemPointer 1 +#define SKIP_OctApiLlm2ListInit 1 +#define SKIP_OctApiLlm2ListCreate 1 +#define SKIP_OctApiLlm2ListDelete 1 +#define SKIP_OctApiLlm2ListLength 1 +#define SKIP_OctApiLlm2ListItemData 1 +#define SKIP_OctApiLlm2ListInsertItem 1 +#define SKIP_OctApiLlm2ListRemoveItem 1 +#define SKIP_OctApiLlmMemCpy 1 + +#endif + diff --git a/xpp/oct612x/include/oct6100api/oct6100_adpcm_chan_inst.h b/xpp/oct612x/include/oct6100api/oct6100_adpcm_chan_inst.h new file mode 100644 index 0000000..9e33909 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_adpcm_chan_inst.h @@ -0,0 +1,74 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_adpcm_chan_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_adpcm_chan.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_adpcm_chan_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 6 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_ADPCM_CHAN_INST_H__ +#define __OCT6100_ADPCM_CHAN_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_ADPCM_CHAN_ +{ + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Count used to manage entry handles allocated to user. */ + UINT8 byEntryOpenCnt; + + /* TSI chariot memory entry. */ + UINT16 usTsiMemIndex; + + /* ADPCM memory entry. */ + UINT16 usAdpcmMemIndex; + + /* Input and output timeslot information. */ + UINT16 usInputTimeslot; + UINT16 usInputStream; + UINT8 byInputNumTssts; + UINT8 byInputPcmLaw; + + UINT16 usOutputTimeslot; + UINT16 usOutputStream; + UINT8 byOutputNumTssts; + UINT8 byOutputPcmLaw; + + /* Internal info for quick access to structures associated to this TSI cnct. */ + UINT16 usInputTsstIndex; + UINT16 usOutputTsstIndex; + +} tOCT6100_API_ADPCM_CHAN, *tPOCT6100_API_ADPCM_CHAN; + +#endif /* __OCT6100_ADPCM_CHAN_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_adpcm_chan_pub.h b/xpp/oct612x/include/oct6100api/oct6100_adpcm_chan_pub.h new file mode 100644 index 0000000..e29fac4 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_adpcm_chan_pub.h @@ -0,0 +1,90 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_adpcm_chan_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_adpcm_chan.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_adpcm_chan_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 5 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_ADPCM_CHAN_PUB_H__ +#define __OCT6100_ADPCM_CHAN_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_ADPCM_CHAN_OPEN_ +{ + PUINT32 pulChanHndl; + + UINT32 ulInputTimeslot; + UINT32 ulInputStream; + UINT32 ulInputNumTssts; + UINT32 ulInputPcmLaw; + + UINT32 ulOutputTimeslot; + UINT32 ulOutputStream; + UINT32 ulOutputNumTssts; + UINT32 ulOutputPcmLaw; + + UINT32 ulChanMode; /* Encoding or decoding. */ + + UINT32 ulEncodingRate; + UINT32 ulDecodingRate; + + UINT32 ulAdpcmNibblePosition; + +} tOCT6100_ADPCM_CHAN_OPEN, *tPOCT6100_ADPCM_CHAN_OPEN; + +typedef struct _OCT6100_ADPCM_CHAN_CLOSE_ +{ + UINT32 ulChanHndl; + +} tOCT6100_ADPCM_CHAN_CLOSE, *tPOCT6100_ADPCM_CHAN_CLOSE; + + +/************************** FUNCTION PROTOTYPES *****************************/ + + +UINT32 Oct6100AdpcmChanOpenDef( + OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ); +UINT32 Oct6100AdpcmChanOpen( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ); + +UINT32 Oct6100AdpcmChanCloseDef( + OUT tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose ); +UINT32 Oct6100AdpcmChanClose( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose ); + +#endif /* __OCT6100_ADPCM_CHAN_PUB_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_api.h b/xpp/oct612x/include/oct6100api/oct6100_api.h new file mode 100644 index 0000000..35a9666 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_api.h @@ -0,0 +1,84 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_api.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Header file containing all definitions used throughout the API. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 23 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_API_H__ +#define __OCT6100_API_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100_defines.h" +#include "oct6100_errors.h" + +#include "oct6100_apiud.h" +#include "oct6100_tlv_inst.h" +#include "oct6100_chip_stats_inst.h" +#include "oct6100_tsi_cnct_inst.h" +#include "oct6100_mixer_inst.h" +#include "oct6100_events_inst.h" +#include "oct6100_tone_detection_inst.h" +#include "oct6100_conf_bridge_inst.h" +#include "oct6100_playout_buf_inst.h" + +#include "oct6100_adpcm_chan_inst.h" +#include "oct6100_phasing_tsst_inst.h" +#include "oct6100_channel_inst.h" +#include "oct6100_interrupts_inst.h" +#include "oct6100_remote_debug_inst.h" +#include "oct6100_debug_inst.h" +#include "oct6100_chip_open_inst.h" +#include "oct6100_api_inst.h" + +#include "oct6100_interrupts_pub.h" +#include "oct6100_tsi_cnct_pub.h" +#include "oct6100_events_pub.h" +#include "oct6100_tone_detection_pub.h" +#include "oct6100_mixer_pub.h" +#include "oct6100_conf_bridge_pub.h" +#include "oct6100_playout_buf_pub.h" + +#include "oct6100_channel_pub.h" +#include "oct6100_remote_debug_pub.h" +#include "oct6100_debug_pub.h" +#include "oct6100_chip_open_pub.h" +#include "oct6100_chip_stats_pub.h" +#include "oct6100_adpcm_chan_pub.h" +#include "oct6100_phasing_tsst_pub.h" + +#ifdef __cplusplus +} +#endif + +#endif /* __OCT6100_API_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_api_inst.h b/xpp/oct612x/include/oct6100api/oct6100_api_inst.h new file mode 100644 index 0000000..29bd0fd --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_api_inst.h @@ -0,0 +1,138 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_api_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing the definition of the API instance structure. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 40 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_API_INST_H__ +#define __OCT6100_API_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_SHARED_INFO_ +{ + /* Local copy of chip configuration structure. */ + tOCT6100_API_CHIP_CONFIG ChipConfig; + + /* Miscellaneous calculations and mapping of static structures in external memory. */ + tOCT6100_API_MISCELLANEOUS MiscVars; + tOCT6100_API_MEMORY_MAP MemoryMap; + + /* Error stats structure. */ + tOCT6100_API_CHIP_ERROR_STATS ErrorStats; + tOCT6100_API_CHIP_STATS ChipStats; + + /* Mixer information. */ + tOCT6100_API_MIXER MixerInfo; + + /* Image breakdown information. */ + tOCT6100_API_IMAGE_REGION ImageRegion[ cOCT6100_MAX_IMAGE_REGION ]; + tOCT6100_API_IMAGE_INFO ImageInfo; + + /* Configuration and management of interrupts. */ + tOCT6100_API_INTRPT_CONFIG IntrptConfig; + tOCT6100_API_INTRPT_MANAGE IntrptManage; + /* Remote debugging. */ + tOCT6100_API_REMOTE_DEBUG_INFO RemoteDebugInfo; + /* Chip debugging information. */ + tOCT6100_API_DEBUG DebugInfo; + + /* Management variables of software and hardware buffers. */ + tOCT6100_API_SOFT_BUFS SoftBufs; + + /* Caller buffer playout memory management structure. */ + tOCT6100_API_BUFFER_PLAYOUT_MALLOC_INFO PlayoutInfo; + + + + UINT32 ulChannelListOfst; + UINT32 ulChannelAllocOfst; + + UINT32 ulConversionMemoryAllocOfst; + + UINT32 ulTsiMemoryAllocOfst; + UINT32 ulExtraTsiMemoryAllocOfst; + UINT32 ulEchoMemoryAllocOfst; + + UINT32 ulTsstAllocOfst; + UINT32 ulTsstListOfst; + UINT32 ulTsstListAllocOfst; + + UINT32 ulTsiCnctListOfst; + UINT32 ulTsiCnctAllocOfst; + + UINT32 ulMixerEventListOfst; + UINT32 ulMixerEventAllocOfst; + + UINT32 ulCopyEventListOfst; + UINT32 ulCopyEventAllocOfst; + + UINT32 ulBiDirChannelListOfst; + UINT32 ulBiDirChannelAllocOfst; + + UINT32 ulConfBridgeListOfst; + UINT32 ulConfBridgeAllocOfst; + + UINT32 ulFlexConfParticipantListOfst; + UINT32 ulFlexConfParticipantAllocOfst; + + UINT32 ulPlayoutBufListOfst; + UINT32 ulPlayoutBufAllocOfst; + UINT32 ulPlayoutBufMemoryNodeListOfst; + + + + UINT32 ulAdpcmChanListOfst; + UINT32 ulAdpcmChanAllocOfst; + + UINT32 ulPhasingTsstListOfst; + UINT32 ulPhasingTsstAllocOfst; + +} tOCT6100_SHARED_INFO, *tPOCT6100_SHARED_INFO; + +typedef struct _OCT6100_INSTANCE_API_ +{ + /* Pointer to portion of API instance structure shared amongst all processes. */ + tPOCT6100_SHARED_INFO pSharedInfo; + + /* Pointer to user-supplied, process context structure. The structure is + a parameter to all user-supplied functions. */ + PVOID pProcessContext; + + /* Handles to all serialization objects used by the API. */ + tOCT6100_USER_SERIAL_OBJECT ulApiSerObj; + + +} tOCT6100_INSTANCE_API, *tPOCT6100_INSTANCE_API; + +#endif /* __OCT6100_API_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_apimi.h b/xpp/oct612x/include/oct6100api/oct6100_apimi.h new file mode 100644 index 0000000..dd584ea --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_apimi.h @@ -0,0 +1,69 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_apimi.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the declaration of all functions exported from the + APIMI block. The APIMI block contains only one function: + Oct6100InterruptMask. + The function is used to mask out the interrupt pin of the chip. This + function is used when a deferred procedure call treats the interrupt (new + interrupts must not be generated until the signalled interrupt is treated). + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 6 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_APIMI_H__ +#define __OCT6100_APIMI_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_INTERRUPT_MASK_ +{ + UINT32 ulUserChipIndex; + PVOID pProcessContext; + + +} tOCT6100_INTERRUPT_MASK, *tPOCT6100_INTERRUPT_MASK; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100InterruptMaskDef( + OUT tPOCT6100_INTERRUPT_MASK f_pInterruptMask ); +UINT32 Oct6100InterruptMask( + IN tPOCT6100_INTERRUPT_MASK f_pInterruptMask ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __OCT6100_APIMI_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_apiud.h b/xpp/oct612x/include/oct6100api/oct6100_apiud.h new file mode 100644 index 0000000..feff93e --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_apiud.h @@ -0,0 +1,312 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_apiud.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Header file containing the definitions and prototypes that are to be + completed by the user. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 16 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_APIUD_H__ +#define __OCT6100_APIUD_H__ + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +/***************************** DEFINES *************************************/ + + +/* Determines the maximum length of a burst of reads/writes. This value must + be in the range 8 - 1024. This value obtains best performance if set to + a power of 2 (i.e. 2^n). */ +#define cOCT6100_MAX_RW_ACCESSES 32 + +/* The define used to specify that the Oct6100SeizeSerializeObject function + is not to return until the specified serialization object has been seized. */ +#define cOCT6100_WAIT_INFINITELY 0xFFFFFFFF + + +/* Compile option: enabling this compile option inserts code to check every + call to a user provided function to make sure the function parameters + are not changed, as required by the API specification. */ +#define cOCT6100_USER_FUNCTION_CHECK + + + +#define cOCT6100_GET_TIME_FAILED_0 0xFFFF0000 +#define cOCT6100_GET_TIME_FAILED_1 0xFFFF0001 +#define cOCT6100_GET_TIME_FAILED_2 0xFFFF0002 +#define cOCT6100_GET_TIME_FAILED_3 0xFFFF0003 +#define cOCT6100_GET_TIME_FAILED_4 0xFFFF0004 + +#define cOCT6100_CREATE_SERIAL_FAILED_0 0xFFFF0010 +#define cOCT6100_CREATE_SERIAL_FAILED_1 0xFFFF0011 +#define cOCT6100_CREATE_SERIAL_FAILED_2 0xFFFF0012 +#define cOCT6100_CREATE_SERIAL_FAILED_3 0xFFFF0013 +#define cOCT6100_CREATE_SERIAL_FAILED_4 0xFFFF0014 + +#define cOCT6100_DESTROY_SERIAL_FAILED_0 0xFFFF0020 +#define cOCT6100_DESTROY_SERIAL_FAILED_1 0xFFFF0021 +#define cOCT6100_DESTROY_SERIAL_FAILED_2 0xFFFF0022 +#define cOCT6100_DESTROY_SERIAL_FAILED_3 0xFFFF0023 +#define cOCT6100_DESTROY_SERIAL_FAILED_4 0xFFFF0024 + +#define cOCT6100_INVALID_SERIAL_HANDLE_0 0xFFFF0030 +#define cOCT6100_INVALID_SERIAL_HANDLE_1 0xFFFF0031 +#define cOCT6100_INVALID_SERIAL_HANDLE_2 0xFFFF0032 +#define cOCT6100_INVALID_SERIAL_HANDLE_3 0xFFFF0033 +#define cOCT6100_INVALID_SERIAL_HANDLE_4 0xFFFF0034 + +#define cOCT6100_RELEASE_SERIAL_FAILED_0 0xFFFF0040 +#define cOCT6100_RELEASE_SERIAL_FAILED_1 0xFFFF0041 +#define cOCT6100_RELEASE_SERIAL_FAILED_2 0xFFFF0042 +#define cOCT6100_RELEASE_SERIAL_FAILED_3 0xFFFF0043 +#define cOCT6100_RELEASE_SERIAL_FAILED_4 0xFFFF0044 + +#define cOCT6100_SEIZE_SERIAL_FAILED_0 0xFFFF0050 +#define cOCT6100_SEIZE_SERIAL_FAILED_1 0xFFFF0051 +#define cOCT6100_SEIZE_SERIAL_FAILED_2 0xFFFF0052 +#define cOCT6100_SEIZE_SERIAL_FAILED_3 0xFFFF0053 +#define cOCT6100_SEIZE_SERIAL_FAILED_4 0xFFFF0054 + +#define cOCT6100_DRIVER_WRITE_FAILED_0 0xFFFF0060 +#define cOCT6100_DRIVER_WRITE_FAILED_1 0xFFFF0061 +#define cOCT6100_DRIVER_WRITE_FAILED_2 0xFFFF0062 +#define cOCT6100_DRIVER_WRITE_FAILED_3 0xFFFF0063 +#define cOCT6100_DRIVER_WRITE_FAILED_4 0xFFFF0064 + +#define cOCT6100_DRIVER_WSMEAR_FAILED_0 0xFFFF0070 +#define cOCT6100_DRIVER_WSMEAR_FAILED_1 0xFFFF0071 +#define cOCT6100_DRIVER_WSMEAR_FAILED_2 0xFFFF0072 +#define cOCT6100_DRIVER_WSMEAR_FAILED_3 0xFFFF0073 +#define cOCT6100_DRIVER_WSMEAR_FAILED_4 0xFFFF0074 + +#define cOCT6100_DRIVER_WBURST_FAILED_0 0xFFFF0080 +#define cOCT6100_DRIVER_WBURST_FAILED_1 0xFFFF0081 +#define cOCT6100_DRIVER_WBURST_FAILED_2 0xFFFF0082 +#define cOCT6100_DRIVER_WBURST_FAILED_3 0xFFFF0083 +#define cOCT6100_DRIVER_WBURST_FAILED_4 0xFFFF0084 + +#define cOCT6100_DRIVER_READ_FAILED_0 0xFFFF0090 +#define cOCT6100_DRIVER_READ_FAILED_1 0xFFFF0091 +#define cOCT6100_DRIVER_READ_FAILED_2 0xFFFF0092 +#define cOCT6100_DRIVER_READ_FAILED_3 0xFFFF0093 +#define cOCT6100_DRIVER_READ_FAILED_4 0xFFFF0094 + +#define cOCT6100_DRIVER_RBURST_FAILED_0 0xFFFF00A0 +#define cOCT6100_DRIVER_RBURST_FAILED_1 0xFFFF00A1 +#define cOCT6100_DRIVER_RBURST_FAILED_2 0xFFFF00A2 +#define cOCT6100_DRIVER_RBURST_FAILED_3 0xFFFF00A3 +#define cOCT6100_DRIVER_RBURST_FAILED_4 0xFFFF00A4 + + + + + +/***************************** TYPES ***************************************/ + +/*Change this type if your platform uses 64bits semaphores/locks */ +typedef UINT32 tOCT6100_USER_SERIAL_OBJECT; + +typedef struct _OCT6100_GET_TIME_ +{ + PVOID pProcessContext; + UINT32 aulWallTimeUs[ 2 ]; + +} tOCT6100_GET_TIME, *tPOCT6100_GET_TIME; + + + + + +typedef struct _OCT6100_CREATE_SERIALIZE_OBJECT_ +{ + PVOID pProcessContext; + PSZ pszSerialObjName; + tOCT6100_USER_SERIAL_OBJECT ulSerialObjHndl; + +} tOCT6100_CREATE_SERIALIZE_OBJECT, *tPOCT6100_CREATE_SERIALIZE_OBJECT; + + +typedef struct _OCT6100_DESTROY_SERIALIZE_OBJECT_ +{ + PVOID pProcessContext; + tOCT6100_USER_SERIAL_OBJECT ulSerialObjHndl; + +} tOCT6100_DESTROY_SERIALIZE_OBJECT, *tPOCT6100_DESTROY_SERIALIZE_OBJECT; + + +typedef struct _OCT6100_SEIZE_SERIALIZE_OBJECT_ +{ + PVOID pProcessContext; + tOCT6100_USER_SERIAL_OBJECT ulSerialObjHndl; + UINT32 ulTryTimeMs; + +} tOCT6100_SEIZE_SERIALIZE_OBJECT, *tPOCT6100_SEIZE_SERIALIZE_OBJECT; + + +typedef struct _OCT6100_RELEASE_SERIALIZE_OBJECT_ +{ + PVOID pProcessContext; + tOCT6100_USER_SERIAL_OBJECT ulSerialObjHndl; + +} tOCT6100_RELEASE_SERIALIZE_OBJECT, *tPOCT6100_RELEASE_SERIALIZE_OBJECT; + + +typedef struct _OCT6100_WRITE_PARAMS_ +{ + PVOID pProcessContext; + + UINT32 ulUserChipId; + UINT32 ulWriteAddress; + UINT16 usWriteData; + +} tOCT6100_WRITE_PARAMS, *tPOCT6100_WRITE_PARAMS; + + +typedef struct _OCT6100_WRITE_SMEAR_PARAMS_ +{ + PVOID pProcessContext; + + UINT32 ulUserChipId; + UINT32 ulWriteAddress; + UINT32 ulWriteLength; + UINT16 usWriteData; + +} tOCT6100_WRITE_SMEAR_PARAMS, *tPOCT6100_WRITE_SMEAR_PARAMS; + + +typedef struct _OCT6100_WRITE_BURST_PARAMS_ +{ + PVOID pProcessContext; + + UINT32 ulUserChipId; + UINT32 ulWriteAddress; + UINT32 ulWriteLength; + PUINT16 pusWriteData; + +} tOCT6100_WRITE_BURST_PARAMS, *tPOCT6100_WRITE_BURST_PARAMS; + + +typedef struct _OCT6100_READ_PARAMS_ +{ + PVOID pProcessContext; + + UINT32 ulUserChipId; + UINT32 ulReadAddress; + PUINT16 pusReadData; + +} tOCT6100_READ_PARAMS, *tPOCT6100_READ_PARAMS; + + +typedef struct _OCT6100_READ_BURST_PARAMS_ +{ + PVOID pProcessContext; + + UINT32 ulUserChipId; + UINT32 ulReadAddress; + UINT32 ulReadLength; + PUINT16 pusReadData; + +} tOCT6100_READ_BURST_PARAMS, *tPOCT6100_READ_BURST_PARAMS; + + + + + + + + +/************************** FUNCTION PROTOTYPES *****************************/ + +/* Time function. */ +UINT32 Oct6100UserGetTime( + IN OUT tPOCT6100_GET_TIME f_pTime ); + + + +/* Memory management functions. */ +UINT32 Oct6100UserMemSet( + IN PVOID f_pAddress, + IN UINT32 f_ulPattern, + IN UINT32 f_ulLength ); + +UINT32 Oct6100UserMemCopy( + IN PVOID f_pDestination, + IN const void *f_pSource, + IN UINT32 f_ulLength ); + +/* Serialization functions. */ +UINT32 Oct6100UserCreateSerializeObject( + IN OUT tPOCT6100_CREATE_SERIALIZE_OBJECT f_pCreate); + +UINT32 Oct6100UserDestroySerializeObject( + IN tPOCT6100_DESTROY_SERIALIZE_OBJECT f_pDestroy); + +UINT32 Oct6100UserSeizeSerializeObject( + IN tPOCT6100_SEIZE_SERIALIZE_OBJECT f_pSeize); + +UINT32 Oct6100UserReleaseSerializeObject( + IN tPOCT6100_RELEASE_SERIALIZE_OBJECT f_pRelease); + +/* Read/Write functions.*/ +UINT32 Oct6100UserDriverWriteApi( + IN tPOCT6100_WRITE_PARAMS f_pWriteParams ); + +UINT32 Oct6100UserDriverWriteOs( + IN tPOCT6100_WRITE_PARAMS f_pWriteParams ); + +UINT32 Oct6100UserDriverWriteSmearApi( + IN tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams ); + +UINT32 Oct6100UserDriverWriteSmearOs( + IN tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams ); + +UINT32 Oct6100UserDriverWriteBurstApi( + IN tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams ); + +UINT32 Oct6100UserDriverWriteBurstOs( + IN tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams ); + +UINT32 Oct6100UserDriverReadApi( + IN OUT tPOCT6100_READ_PARAMS f_pReadParams ); + +UINT32 Oct6100UserDriverReadOs( + IN OUT tPOCT6100_READ_PARAMS f_pReadParams ); + +UINT32 Oct6100UserDriverReadBurstApi( + IN OUT tPOCT6100_READ_BURST_PARAMS f_pBurstParams ); + +UINT32 Oct6100UserDriverReadBurstOs( + IN OUT tPOCT6100_READ_BURST_PARAMS f_pBurstParams ); + + + + + + + +#endif /* __OCT6100_APIUD_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_channel_inst.h b/xpp/oct612x/include/oct6100api/oct6100_channel_inst.h new file mode 100644 index 0000000..5b71bb0 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_channel_inst.h @@ -0,0 +1,374 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_channel_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_channel.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_channel_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 90 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHANNEL_INST_H__ +#define __OCT6100_CHANNEL_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/***************************** TYPES ***************************************/ + +#ifndef __KERNEL__ +#include +#endif + +#ifndef PTR_TYPE +#define PTR_TYPE UINT16 +#endif + +typedef struct _OCT6100_API_CHANNEL_TDM_ +{ + /* Laws. */ + UINT8 byRinPcmLaw : 1; + UINT8 bySinPcmLaw : 1; + UINT8 byRoutPcmLaw : 1; + UINT8 bySoutPcmLaw : 1; + + UINT8 byRinNumTssts : 1; + UINT8 bySinNumTssts : 1; + UINT8 byRoutNumTssts : 1; + UINT8 bySoutNumTssts : 1; + + /* RIN port. */ + UINT16 usRinTimeslot; + UINT16 usRinStream; + + /* SIN port. */ + UINT16 usSinTimeslot; + UINT16 usSinStream; + + /* ROUT port. */ + UINT16 usRoutTimeslot; + UINT16 usRoutStream; + + /* SOUT port. */ + UINT16 usSoutTimeslot; + UINT16 usSoutStream; + + /* ROUT broadcast info. */ + UINT16 usRoutBrdcastTsstFirstEntry; + UINT16 usRoutBrdcastTsstNumEntry; + + /* SOUT broadcast info. */ + UINT16 usSoutBrdcastTsstFirstEntry; + UINT16 usSoutBrdcastTsstNumEntry; + +} tOCT6100_API_CHANNEL_TDM, *tPOCT6100_API_CHANNEL_TDM; + +typedef struct _OCT6100_API_CHANNEL_VQE_ +{ + UINT8 fEnableNlp : 1; + UINT8 fEnableTailDisplacement : 1; + UINT8 fSinDcOffsetRemoval : 1; + UINT8 fRinDcOffsetRemoval : 1; + UINT8 fRinLevelControl : 1; + UINT8 fSoutLevelControl : 1; + UINT8 fRinAutomaticLevelControl : 1; + UINT8 fSoutAutomaticLevelControl : 1; + UINT8 fRinHighLevelCompensation : 1; + UINT8 fSoutAdaptiveNoiseReduction : 1; + UINT8 fDtmfToneRemoval : 1; + UINT8 fAcousticEcho : 1; + UINT8 byComfortNoiseMode : 1; + UINT8 fSoutNaturalListenerEnhancement : 1; + UINT8 fRoutNoiseReduction : 1; + UINT8 fEnableMusicProtection : 1; + UINT8 fIdleCodeDetection : 1; + UINT8 byAnrVoiceNoiseSegregation : 1; + UINT8 byDoubleTalkBehavior : 1; + UINT8 fSoutNoiseBleaching : 1; + UINT8 fSoutConferencingNoiseReduction : 1; + UINT8 bySoutAutomaticListenerEnhancementGainDb : 1; + UINT8 byNonLinearityBehaviorA : 1; + UINT8 byNonLinearityBehaviorB : 1; + UINT8 bySoutNaturalListenerEnhancementGainDb : 1; + + OCT_INT8 chRinAutomaticLevelControlTargetDb; + OCT_INT8 chSoutAutomaticLevelControlTargetDb; + + OCT_INT8 chRinHighLevelCompensationThresholdDb; + + OCT_INT8 chRinLevelControlGainDb; + OCT_INT8 chSoutLevelControlGainDb; + + OCT_INT8 chDefaultErlDb; + OCT_INT8 chAecDefaultErlDb; + + OCT_INT8 chRoutNoiseReductionLevelGainDb; + OCT_INT8 chAnrSnrEnhancementDb; + + UINT16 usToneDisablerVqeActivationDelay; + UINT16 usAecTailLength; + + UINT16 usTailDisplacement; + UINT16 usTailLength; + +} tOCT6100_API_CHANNEL_VQE, *tPOCT6100_API_CHANNEL_VQE; + +typedef struct _OCT6100_API_CHANNEL_CODEC_ +{ + UINT8 byAdpcmNibblePosition : 1; + UINT8 fEnableSilenceSuppression : 1; + + UINT8 byEncoderPort : 1; + UINT8 byEncodingRate : 1; + + UINT8 byDecoderPort : 1; + UINT8 byDecodingRate : 1; + + UINT8 byPhase : 1; + UINT8 byPhasingType : 1; + +} tOCT6100_API_CHANNEL_CODEC, *tPOCT6100_API_CHANNEL_CODEC; + +typedef struct _OCT6100_API_CHANNEL_ +{ + /*=======================================================================*/ + /* Channel configuration. */ + + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved : 1; + + /* Count used to manage entry handles allocated to user. */ + UINT8 byEntryOpenCnt : 1; + + /* Is this a bidirectionnal channel? */ + UINT8 fBiDirChannel : 1; + + /* Enable tone disabler? */ + UINT8 fEnableToneDisabler : 1; + + /* Current echo operation mode. */ + UINT8 byEchoOperationMode : 1; + + UINT8 byToneDisablerStatus : 1; + + UINT8 fMute : 1; + UINT8 fTap : 1; + UINT8 fBeingTapped : 1; + UINT8 fCopyEventCreated : 1; + + UINT8 fSoutBufPlaying : 1; + UINT8 fRinBufPlaying : 1; + + UINT8 fRinBufPlayoutNotifyOnStop : 1; + UINT8 fRinBufPlayoutRepeatUsed : 1; + + + UINT8 fSoutBufPlayoutNotifyOnStop : 1; + UINT8 fSoutBufPlayoutRepeatUsed : 1; + + UINT8 fRinHardStop : 1; + UINT8 fSoutHardStop : 1; + + UINT8 byRinPlayoutStopEventType : 1; + UINT8 bySoutPlayoutStopEventType : 1; + + UINT8 fRinBufAdded : 1; + UINT8 fSoutBufAdded : 1; + + UINT8 fBufPlayoutActive : 1; + + /* Enable extended tone detection. */ + UINT8 fEnableExtToneDetection : 1; + + /* State of the codec structure associated to this channel. */ + UINT8 fSinSoutCodecActive : 1; + UINT8 fRinRoutCodecActive : 1; + + /* TSI chariot memory entry for the Rin/Rout stream. */ + UINT16 usRinRoutTsiMemIndex; + + /* TSI chariot memory entry for the Sin/Sout stream. */ + UINT16 usSinSoutTsiMemIndex; + + /* Additional TSI entry used to temporarily store the SIN signal. */ + UINT16 usExtraSinTsiMemIndex; + UINT16 usExtraSinTsiDependencyCnt; + + /* Additional TSI entry used to temporarily store the RIN signal. */ + UINT16 usExtraRinTsiMemIndex; + UINT16 usExtraRinTsiDependencyCnt; + + /* Conversion chariot memory entry. */ + UINT16 usRinRoutConversionMemIndex; + UINT16 usSinSoutConversionMemIndex; + + /* TSST control memory entry. */ + UINT16 usRinTsstIndex; + UINT16 usSinTsstIndex; + UINT16 usRoutTsstIndex; + UINT16 usSoutTsstIndex; + + /* SSPX memory entry. */ + UINT16 usEchoMemIndex; + + /* Active mixer events count to test for last event. */ + UINT16 usMixerEventCnt; + + /* Copy events. */ + UINT16 usSinCopyEventIndex; + UINT16 usSoutCopyEventIndex; + + /* Silence events. */ + UINT16 usRinSilenceEventIndex; + UINT16 usSinSilenceEventIndex; + + /* TDM configuration. */ + tOCT6100_API_CHANNEL_TDM TdmConfig; + + /* VQE configuration. */ + tOCT6100_API_CHANNEL_VQE VqeConfig; + + /* Currently muted ports. */ + UINT16 usMutedPorts; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Statistics section. */ + + INT16 sComfortNoiseLevel; + + UINT16 usCurrentEchoDelay; + UINT16 usMaxEchoDelay; + + UINT16 usNumEchoPathChanges; + UINT16 usNumEchoPathChangesOfst; + + INT16 sCurrentERL; + INT16 sCurrentERLE; + + INT16 sMaxERL; + INT16 sMaxERLE; + + INT16 sRinLevel; + INT16 sSinLevel; + + INT16 sRinAppliedGain; + INT16 sSoutAppliedGain; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Bridge information. */ + + UINT16 usBridgeIndex; + + UINT16 usLoadEventIndex; + UINT16 usSubStoreEventIndex; + + UINT16 usFlexConfParticipantIndex; + UINT16 usTapBridgeIndex; + UINT16 usTapChanIndex; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Buffer playout information. */ + + PTR_TYPE ulRinBufWritePtr; + PTR_TYPE ulRinBufSkipPtr; + PTR_TYPE ulSoutBufWritePtr; + PTR_TYPE ulSoutBufSkipPtr; + + /* User channel ID, transparently passed to the user. */ + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Copy events information. */ + + /* Number of copy events created. */ + UINT16 usCopyEventCnt; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Extended tone detection info. */ + + + UINT16 usExtToneChanIndex; + UINT16 usExtToneMixerIndex; + UINT16 usExtToneTsiIndex; + + /* Index of the phasing TSST */ + UINT16 usPhasingTsstIndex; + + /* Mode of operation of the channel based on the extended tone detection configuration. */ + PTR_TYPE ulExtToneChanMode; + + /*=======================================================================*/ + + /* Tone detection state. */ + /* This array is configured as follow. */ + /* Index 0 contain event 0 to 31 and Index 1 contains event 32 - 55 */ + PTR_TYPE ulLastSSToneDetected; + PTR_TYPE ulLastSSToneTimestamp; + + + PTR_TYPE ulRinUserBufPlayoutEventId; + PTR_TYPE ulSoutUserBufPlayoutEventId; + + UINT32 aulToneConf[2]; + UINT32 ulUserChanId; + /*=======================================================================*/ + + + /*=======================================================================*/ + + + /* Codec configuration. */ + tOCT6100_API_CHANNEL_CODEC CodecConfig; + +} tOCT6100_API_CHANNEL, *tPOCT6100_API_CHANNEL; + +typedef struct _OCT6100_API_BIDIR_CHANNEL_ +{ + UINT16 usFirstChanIndex; + UINT16 usSecondChanIndex; + + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved : 1; + /* Count used to manage entry handles allocated to user. */ + UINT8 byEntryOpenCnt : 1; + +} tOCT6100_API_BIDIR_CHANNEL, *tPOCT6100_API_BIDIR_CHANNEL; + +#endif /* __OCT6100_CHANNEL_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_channel_pub.h b/xpp/oct612x/include/oct6100api/oct6100_channel_pub.h new file mode 100644 index 0000000..2691e10 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_channel_pub.h @@ -0,0 +1,547 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_channel_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_channel.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_channel_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 84 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHANNEL_PUB_H__ +#define __OCT6100_CHANNEL_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +/* Channel open structures. */ +typedef struct _OCT6100_CHANNEL_OPEN_TDM_ +{ + UINT32 ulRinNumTssts; + UINT32 ulSinNumTssts; + UINT32 ulRoutNumTssts; + UINT32 ulSoutNumTssts; + + UINT32 ulSinTimeslot; + UINT32 ulSinStream; + UINT32 ulSinPcmLaw; + + UINT32 ulSoutTimeslot; + UINT32 ulSoutStream; + UINT32 ulSoutPcmLaw; + + UINT32 ulRinTimeslot; + UINT32 ulRinStream; + UINT32 ulRinPcmLaw; + + UINT32 ulRoutTimeslot; + UINT32 ulRoutStream; + UINT32 ulRoutPcmLaw; + +} tOCT6100_CHANNEL_OPEN_TDM, *tPOCT6100_CHANNEL_OPEN_TDM; + +typedef struct _OCT6100_CHANNEL_OPEN_VQE_ +{ + BOOL fEnableNlp; + BOOL fEnableTailDisplacement; + UINT32 ulTailDisplacement; + UINT32 ulTailLength; + + BOOL fSinDcOffsetRemoval; + BOOL fRinDcOffsetRemoval; + BOOL fRinLevelControl; + BOOL fSoutLevelControl; + BOOL fRinAutomaticLevelControl; + BOOL fSoutAutomaticLevelControl; + BOOL fRinHighLevelCompensation; + BOOL fAcousticEcho; + BOOL fSoutAdaptiveNoiseReduction; + BOOL fDtmfToneRemoval; + + BOOL fSoutNoiseBleaching; + BOOL fSoutConferencingNoiseReduction; + + UINT32 ulComfortNoiseMode; + UINT32 ulNonLinearityBehaviorA; + UINT32 ulNonLinearityBehaviorB; + + INT32 lRinLevelControlGainDb; + INT32 lSoutLevelControlGainDb; + INT32 lRinAutomaticLevelControlTargetDb; + INT32 lSoutAutomaticLevelControlTargetDb; + INT32 lRinHighLevelCompensationThresholdDb; + INT32 lDefaultErlDb; + INT32 lAecDefaultErlDb; + UINT32 ulAecTailLength; + UINT32 ulSoutAutomaticListenerEnhancementGainDb; + UINT32 ulSoutNaturalListenerEnhancementGainDb; + BOOL fSoutNaturalListenerEnhancement; + BOOL fRoutNoiseReduction; + INT32 lRoutNoiseReductionLevelGainDb; + INT32 lAnrSnrEnhancementDb; + UINT32 ulAnrVoiceNoiseSegregation; + UINT32 ulDoubleTalkBehavior; + + UINT32 ulToneDisablerVqeActivationDelay; + + BOOL fEnableMusicProtection; + BOOL fIdleCodeDetection; + + + +} tOCT6100_CHANNEL_OPEN_VQE, *tPOCT6100_CHANNEL_OPEN_VQE; + +typedef struct _OCT6100_CHANNEL_OPEN_CODEC_ +{ + UINT32 ulAdpcmNibblePosition; + + UINT32 ulEncoderPort; + UINT32 ulEncodingRate; + + UINT32 ulDecoderPort; + UINT32 ulDecodingRate; + + BOOL fEnableSilenceSuppression; + UINT32 ulPhase; + UINT32 ulPhasingType; + UINT32 ulPhasingTsstHndl; + +} tOCT6100_CHANNEL_OPEN_CODEC, *tPOCT6100_CHANNEL_OPEN_CODEC; + +typedef struct _OCT6100_CHANNEL_OPEN_ +{ + PUINT32 pulChannelHndl; + UINT32 ulUserChanId; + + UINT32 ulEchoOperationMode; + + BOOL fEnableToneDisabler; + + BOOL fEnableExtToneDetection; + + tOCT6100_CHANNEL_OPEN_TDM TdmConfig; + tOCT6100_CHANNEL_OPEN_VQE VqeConfig; + tOCT6100_CHANNEL_OPEN_CODEC CodecConfig; + + + +} tOCT6100_CHANNEL_OPEN, *tPOCT6100_CHANNEL_OPEN; + +/* Channel close structure. */ +typedef struct _OCT6100_CHANNEL_CLOSE_ +{ + UINT32 ulChannelHndl; + +} tOCT6100_CHANNEL_CLOSE, *tPOCT6100_CHANNEL_CLOSE; + +/* Channel modify structures. */ +typedef struct _OCT6100_CHANNEL_MODIFY_TDM_ +{ + UINT32 ulRinNumTssts; + UINT32 ulSinNumTssts; + UINT32 ulRoutNumTssts; + UINT32 ulSoutNumTssts; + + UINT32 ulSinTimeslot; + UINT32 ulSinStream; + UINT32 ulSinPcmLaw; + + UINT32 ulSoutTimeslot; + UINT32 ulSoutStream; + UINT32 ulSoutPcmLaw; + + UINT32 ulRinTimeslot; + UINT32 ulRinStream; + UINT32 ulRinPcmLaw; + + UINT32 ulRoutTimeslot; + UINT32 ulRoutStream; + UINT32 ulRoutPcmLaw; + +} tOCT6100_CHANNEL_MODIFY_TDM, *tPOCT6100_CHANNEL_MODIFY_TDM; + +typedef struct _OCT6100_CHANNEL_MODIFY_VQE_ +{ + BOOL fEnableNlp; + BOOL fEnableTailDisplacement; + UINT32 ulTailDisplacement; + + BOOL fSinDcOffsetRemoval; + BOOL fRinDcOffsetRemoval; + BOOL fRinLevelControl; + BOOL fSoutLevelControl; + BOOL fRinAutomaticLevelControl; + BOOL fSoutAutomaticLevelControl; + BOOL fRinHighLevelCompensation; + BOOL fAcousticEcho; + BOOL fSoutAdaptiveNoiseReduction; + BOOL fDtmfToneRemoval; + + BOOL fSoutConferencingNoiseReduction; + BOOL fSoutNoiseBleaching; + + UINT32 ulNonLinearityBehaviorA; + UINT32 ulNonLinearityBehaviorB; + UINT32 ulComfortNoiseMode; + + INT32 lRinLevelControlGainDb; + INT32 lSoutLevelControlGainDb; + INT32 lRinAutomaticLevelControlTargetDb; + INT32 lSoutAutomaticLevelControlTargetDb; + INT32 lRinHighLevelCompensationThresholdDb; + INT32 lDefaultErlDb; + INT32 lAecDefaultErlDb; + UINT32 ulAecTailLength; + UINT32 ulSoutAutomaticListenerEnhancementGainDb; + UINT32 ulSoutNaturalListenerEnhancementGainDb; + BOOL fSoutNaturalListenerEnhancement; + BOOL fRoutNoiseReduction; + INT32 lRoutNoiseReductionLevelGainDb; + INT32 lAnrSnrEnhancementDb; + UINT32 ulAnrVoiceNoiseSegregation; + UINT32 ulDoubleTalkBehavior; + + UINT32 ulToneDisablerVqeActivationDelay; + + BOOL fEnableMusicProtection; + BOOL fIdleCodeDetection; + + + +} tOCT6100_CHANNEL_MODIFY_VQE, *tPOCT6100_CHANNEL_MODIFY_VQE; + +typedef struct _OCT6100_CHANNEL_MODIFY_CODEC_ +{ + UINT32 ulEncoderPort; + UINT32 ulEncodingRate; + + UINT32 ulDecoderPort; + UINT32 ulDecodingRate; + + BOOL fEnableSilenceSuppression; + UINT32 ulPhase; + UINT32 ulPhasingType; + UINT32 ulPhasingTsstHndl; + +} tOCT6100_CHANNEL_MODIFY_CODEC, *tPOCT6100_CHANNEL_MODIFY_CODEC; + +typedef struct _OCT6100_CHANNEL_MODIFY_ +{ + UINT32 ulChannelHndl; + UINT32 ulUserChanId; + UINT32 ulEchoOperationMode; + + BOOL fEnableToneDisabler; + + BOOL fApplyToAllChannels; + + BOOL fDisableToneDetection; + BOOL fStopBufferPlayout; + BOOL fRemoveConfBridgeParticipant; + BOOL fRemoveBroadcastTssts; + + BOOL fTdmConfigModified; /* TRUE/FALSE */ + BOOL fVqeConfigModified; /* TRUE/FALSE */ + BOOL fCodecConfigModified; /* TRUE/FALSE */ + + + tOCT6100_CHANNEL_MODIFY_TDM TdmConfig; + tOCT6100_CHANNEL_MODIFY_VQE VqeConfig; + tOCT6100_CHANNEL_MODIFY_CODEC CodecConfig; + +} tOCT6100_CHANNEL_MODIFY, *tPOCT6100_CHANNEL_MODIFY; + +typedef struct _OCT6100_CHANNEL_BROADCAST_TSST_ADD_ +{ + UINT32 ulChannelHndl; + + UINT32 ulPort; + UINT32 ulTimeslot; + UINT32 ulStream; + +} tOCT6100_CHANNEL_BROADCAST_TSST_ADD, *tPOCT6100_CHANNEL_BROADCAST_TSST_ADD; + +typedef struct _OCT6100_CHANNEL_BROADCAST_TSST_REMOVE_ +{ + UINT32 ulChannelHndl; + + UINT32 ulPort; + UINT32 ulTimeslot; + UINT32 ulStream; + + BOOL fRemoveAll; + +} tOCT6100_CHANNEL_BROADCAST_TSST_REMOVE, *tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE; + +/* Channel open structures.*/ +typedef struct _OCT6100_CHANNEL_STATS_TDM_ +{ + UINT32 ulMaxBroadcastTssts; + UINT32 ulNumRoutBroadcastTssts; + BOOL fMoreRoutBroadcastTssts; + UINT32 ulNumSoutBroadcastTssts; + BOOL fMoreSoutBroadcastTssts; + + UINT32 ulSinNumTssts; + UINT32 ulSoutNumTssts; + UINT32 ulRinNumTssts; + UINT32 ulRoutNumTssts; + + UINT32 ulSinTimeslot; + UINT32 ulSinStream; + UINT32 ulSinPcmLaw; + + UINT32 ulSoutTimeslot; + UINT32 ulSoutStream; + UINT32 ulSoutPcmLaw; + + PUINT32 pulSoutBroadcastTimeslot; + PUINT32 pulSoutBroadcastStream; + + UINT32 ulRinTimeslot; + UINT32 ulRinStream; + UINT32 ulRinPcmLaw; + + UINT32 ulRoutTimeslot; + UINT32 ulRoutStream; + UINT32 ulRoutPcmLaw; + + PUINT32 pulRoutBroadcastTimeslot; + PUINT32 pulRoutBroadcastStream; + +} tOCT6100_CHANNEL_STATS_TDM, *tPOCT6100_CHANNEL_STATS_TDM; + +typedef struct _OCT6100_CHANNEL_STATS_VQE_ +{ + BOOL fEnableNlp; + BOOL fEnableTailDisplacement; + UINT32 ulTailDisplacement; + UINT32 ulTailLength; + + BOOL fSinDcOffsetRemoval; + BOOL fRinDcOffsetRemoval; + BOOL fRinLevelControl; + BOOL fSoutLevelControl; + BOOL fRinAutomaticLevelControl; + BOOL fSoutAutomaticLevelControl; + BOOL fRinHighLevelCompensation; + BOOL fAcousticEcho; + BOOL fSoutAdaptiveNoiseReduction; + BOOL fDtmfToneRemoval; + + BOOL fSoutConferencingNoiseReduction; + BOOL fSoutNoiseBleaching; + + UINT32 ulComfortNoiseMode; + UINT32 ulNonLinearityBehaviorA; + UINT32 ulNonLinearityBehaviorB; + + INT32 lRinLevelControlGainDb; + INT32 lSoutLevelControlGainDb; + INT32 lRinAutomaticLevelControlTargetDb; + INT32 lSoutAutomaticLevelControlTargetDb; + INT32 lRinHighLevelCompensationThresholdDb; + INT32 lDefaultErlDb; + INT32 lAecDefaultErlDb; + UINT32 ulAecTailLength; + UINT32 ulSoutAutomaticListenerEnhancementGainDb; + UINT32 ulSoutNaturalListenerEnhancementGainDb; + BOOL fSoutNaturalListenerEnhancement; + BOOL fRoutNoiseReduction; + INT32 lRoutNoiseReductionLevelGainDb; + INT32 lAnrSnrEnhancementDb; + UINT32 ulAnrVoiceNoiseSegregation; + UINT32 ulDoubleTalkBehavior; + + UINT32 ulToneDisablerVqeActivationDelay; + + BOOL fEnableMusicProtection; + BOOL fIdleCodeDetection; + + + +} tOCT6100_CHANNEL_STATS_VQE, *tPOCT6100_CHANNEL_STATS_VQE; + +typedef struct _OCT6100_CHANNEL_STATS_CODEC_ +{ + UINT32 ulAdpcmNibblePosition; + + UINT32 ulEncoderPort; + UINT32 ulEncodingRate; + + UINT32 ulDecoderPort; + UINT32 ulDecodingRate; + + BOOL fEnableSilenceSuppression; + UINT32 ulPhase; + UINT32 ulPhasingType; + UINT32 ulPhasingTsstHndl; + +} tOCT6100_CHANNEL_STATS_CODEC, *tPOCT6100_CHANNEL_STATS_CODEC; + +typedef struct _OCT6100_CHANNEL_STATS_ +{ + BOOL fResetStats; + + UINT32 ulChannelHndl; + UINT32 ulUserChanId; + + UINT32 ulEchoOperationMode; + BOOL fEnableToneDisabler; + + UINT32 ulMutePortsMask; + BOOL fEnableExtToneDetection; + + tOCT6100_CHANNEL_STATS_TDM TdmConfig; + tOCT6100_CHANNEL_STATS_VQE VqeConfig; + tOCT6100_CHANNEL_STATS_CODEC CodecConfig; + + /* Real stats. */ + UINT32 ulNumEchoPathChanges; + UINT32 ulToneDisablerStatus; + + INT32 lCurrentERL; + INT32 lCurrentERLE; + UINT32 ulCurrentEchoDelay; + + INT32 lMaxERL; + INT32 lMaxERLE; + UINT32 ulMaxEchoDelay; + + INT32 lRinLevel; + INT32 lSinLevel; + INT32 lRinAppliedGain; + INT32 lSoutAppliedGain; + INT32 lComfortNoiseLevel; + + BOOL fEchoCancellerConverged; + BOOL fSinVoiceDetected; + + + +} tOCT6100_CHANNEL_STATS, *tPOCT6100_CHANNEL_STATS; + +typedef struct _OCT6100_CHANNEL_CREATE_BIDIR_ +{ + PUINT32 pulBiDirChannelHndl; + + UINT32 ulFirstChannelHndl; + UINT32 ulSecondChannelHndl; + + + +} tOCT6100_CHANNEL_CREATE_BIDIR, *tPOCT6100_CHANNEL_CREATE_BIDIR; + +typedef struct _OCT6100_CHANNEL_DESTROY_BIDIR_ +{ + UINT32 ulBiDirChannelHndl; + +} tOCT6100_CHANNEL_DESTROY_BIDIR, *tPOCT6100_CHANNEL_DESTROY_BIDIR; + +typedef struct _OCT6100_CHANNEL_MUTE_ +{ + UINT32 ulChannelHndl; + UINT32 ulPortMask; + +} tOCT6100_CHANNEL_MUTE, *tPOCT6100_CHANNEL_MUTE; + +typedef struct _OCT6100_CHANNEL_UNMUTE_ +{ + UINT32 ulChannelHndl; + UINT32 ulPortMask; + +} tOCT6100_CHANNEL_UNMUTE, *tPOCT6100_CHANNEL_UNMUTE; + + +/************************** FUNCTION PROTOTYPES *****************************/ + + +UINT32 Oct6100ChannelOpenDef( + OUT tPOCT6100_CHANNEL_OPEN f_pChannelOpen ); +UINT32 Oct6100ChannelOpen( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_OPEN f_pChannelOpen ); + +UINT32 Oct6100ChannelCloseDef( + OUT tPOCT6100_CHANNEL_CLOSE f_pChannelClose ); +UINT32 Oct6100ChannelClose( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_CLOSE f_pChannelClose ); + +UINT32 Oct6100ChannelModifyDef( + OUT tPOCT6100_CHANNEL_MODIFY f_pChannelModify ); +UINT32 Oct6100ChannelModify( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_MODIFY f_pChannelModify ); + +UINT32 Oct6100ChannelBroadcastTsstAddDef( + OUT tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd ); +UINT32 Oct6100ChannelBroadcastTsstAdd( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd ); + +UINT32 Oct6100ChannelBroadcastTsstRemoveDef( + OUT tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelTsstRemove ); +UINT32 Oct6100ChannelBroadcastTsstRemove( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelTsstRemove ); + +UINT32 Oct6100ChannelGetStatsDef( + OUT tPOCT6100_CHANNEL_STATS f_pChannelStats ); +UINT32 Oct6100ChannelGetStats( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_STATS f_pChannelStats ); + +UINT32 Oct6100ChannelCreateBiDirDef( + OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir ); +UINT32 Oct6100ChannelCreateBiDir( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir ); + +UINT32 Oct6100ChannelDestroyBiDirDef( + OUT tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir ); +UINT32 Oct6100ChannelDestroyBiDir( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir ); + +UINT32 Oct6100ChannelMuteDef( + OUT tPOCT6100_CHANNEL_MUTE f_pChannelMute ); +UINT32 Oct6100ChannelMute( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_MUTE f_pChannelMute ); + +UINT32 Oct6100ChannelUnMuteDef( + OUT tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute ); +UINT32 Oct6100ChannelUnMute( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute ); + +#endif /* __OCT6100_CHANNEL_PUB_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_chip_open_inst.h b/xpp/oct612x/include/oct6100api/oct6100_chip_open_inst.h new file mode 100644 index 0000000..fdd2bd0 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_chip_open_inst.h @@ -0,0 +1,515 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_open_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_chip_open.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_chip_open_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 122 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHIP_OPEN_INST_H__ +#define __OCT6100_CHIP_OPEN_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_CHIP_CONFIG_ +{ + UINT32 ulUserChipId; + PVOID pProcessContext; + + unsigned char const *pbyImageFile; /* Byte pointer to the image file to be uploaded into the chip. */ + UINT32 ulImageSize; /* Size of the image file (in bytes). */ + + UINT32 ulMemClkFreq; + UINT32 ulUpclkFreq; /* 33.33 or 66.66 MHz. */ + UINT8 fEnableMemClkOut; /* TRUE/FALSE */ + + UINT8 fMultiProcessSystem; + + UINT8 byMemoryType; /* SDRAM or DDR */ + UINT8 byNumMemoryChips; /* Number of memory chips present. */ + UINT32 ulMemoryChipSize; /* The size of the memory chips. */ + + UINT16 usMaxRwAccesses; + UINT16 usTailDisplacement; + + /* Resource allocation parameters. */ + UINT16 usMaxChannels; + UINT16 usMaxBiDirChannels; + + UINT32 aulTdmStreamFreqs[ cOCT6100_TDM_STREAM_MAX_GROUPS ]; + + UINT8 byMaxTdmStreams; + UINT8 byTdmSampling; + + UINT8 fEnableFastH100Mode; + UINT8 fEnableAcousticEcho; /* Acoustic echo enabled. */ + + UINT16 ausTimestampTimeslots[ 4 ]; + UINT16 ausTimestampStreams[ 4 ]; + + UINT8 fUseSynchTimestamp; + + /* Debug feature used to record stream information from a channel.*/ + UINT8 fEnableChannelRecording; + + UINT16 usMaxRemoteDebugSessions; + + UINT8 byInterruptPolarity; + + UINT16 usMaxTsiCncts; + + UINT8 fEnableExtToneDetection; + UINT8 fEnable2100StopEvent; + + + UINT16 usMaxConfBridges; + UINT16 usMaxFlexibleConfParticipants; + UINT16 usMaxPlayoutBuffers; + + /* Playout event software buffer size. */ + UINT32 ulSoftBufPlayoutEventsBufSize; + + /* Soft buffer size. */ + UINT32 ulSoftToneEventsBufSize; + + UINT16 usMaxPhasingTssts; + UINT16 usMaxAdpcmChannels; + + + + + + UINT8 fEnableProductionBist; + UINT32 ulProductionBistMode; + UINT32 ulNumProductionBistLoops; + +} tOCT6100_API_CHIP_CONFIG, *tPOCT6100_API_CHIP_CONFIG; + + +typedef struct _OCT6100_API_MISCELLANEOUS_ +{ + /* Total size of external memories. */ + UINT32 ulTotalMemSize; + + UINT32 ulH100SlaveMode; + + /* Mclk frequency generated by the chip. */ + UINT32 ulMclkFreq; + + /* Array of UINT32s used to perform a burst of writes (avoids having to + allocate on the stack. The size of this array MUST NOT CHANGE (it's + used everywhere). */ + UINT16 ausSuperArray[ cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ]; + + /* Chip ID and revision.*/ + UINT16 usChipId; + UINT16 usChipRevision; + + /* Lsu CPU access variables.*/ + UINT16 usCpuLsuWritePtr; + UINT16 usCodepoint; + + /* Max number of channel supported.*/ + UINT16 usMaxNumberOfChannels; + UINT16 usMaxH100Speed; + UINT16 usTdmClkBoundary; + + UINT16 usNumBridgesOpened; + UINT16 usFirstBridge; + + + + + +} tOCT6100_API_MISCELLANEOUS, *tPOCT6100_API_MISCELLANEOUS; + +typedef struct _OCT6100_API_MEMORY_MAP_ +{ + /*-----------------------------------------------------------------------------*/ + /* Structure contained in external memory. */ + + /* Memory mapping filled using TLV information from the chip. */ + + /* Main channel memory. */ + UINT32 ulChanMainMemBase; + UINT32 ulChanMainMemSize; + + UINT32 ulChanMainIoMemOfst; + + UINT32 ulChanMainRinCBMemOfst; + UINT32 ulChanMainRinCBMemSize; + UINT32 ulChanMainSinCBMemOfst; + UINT32 ulChanMainSinCBMemSize; + UINT32 ulChanMainSoutCBMemOfst; + UINT32 ulChanMainSoutCBMemSize; + + /* Free memory base address. */ + UINT32 ulFreeMemBaseAddress; + + /* Root channel config offset. */ + UINT32 ulChanRootConfOfst; + + /* Playout buffer info. */ + UINT32 ulChanMainRinPlayoutMemOfst; + UINT32 ulChanMainRinPlayoutMemSize; + UINT32 ulChanMainSoutPlayoutMemOfst; + UINT32 ulChanMainSoutPlayoutMemSize; + + /* Channel Stats location */ + UINT32 ulChanMainIoStatsOfst; + UINT32 ulChanMainIoStatsSize; + + /* Buffer playout fields. */ + tOCT6100_TLV_OFFSET PlayoutRinWritePtrOfst; + tOCT6100_TLV_OFFSET PlayoutRinIgnoreSkipCleanOfst; + tOCT6100_TLV_OFFSET PlayoutRinSkipPtrOfst; + tOCT6100_TLV_OFFSET PlayoutSoutWritePtrOfst; + tOCT6100_TLV_OFFSET PlayoutSoutIgnoreSkipCleanOfst; + tOCT6100_TLV_OFFSET PlayoutSoutSkipPtrOfst; + tOCT6100_TLV_OFFSET PlayoutRinReadPtrOfst; + tOCT6100_TLV_OFFSET PlayoutSoutReadPtrOfst; + tOCT6100_TLV_OFFSET PlayoutRinHardSkipOfst; + tOCT6100_TLV_OFFSET PlayoutSoutHardSkipOfst; + + /* Adaptive noise reduction. */ + tOCT6100_TLV_OFFSET AdaptiveNoiseReductionOfst; + + /* DC offset removal. */ + tOCT6100_TLV_OFFSET RinDcOffsetRemovalOfst; + tOCT6100_TLV_OFFSET SinDcOffsetRemovalOfst; + + /* Level control. */ + tOCT6100_TLV_OFFSET RinLevelControlOfst; + tOCT6100_TLV_OFFSET SoutLevelControlOfst; + + /* Auto level control. */ + tOCT6100_TLV_OFFSET RinAutoLevelControlTargetOfst; + tOCT6100_TLV_OFFSET SoutAutoLevelControlTargetOfst; + + /* High level compensation. */ + tOCT6100_TLV_OFFSET RinHighLevelCompensationThresholdOfst; + tOCT6100_TLV_OFFSET SoutHighLevelCompensationThresholdOfst; + + /* Auto level control and high level compensation status. */ + tOCT6100_TLV_OFFSET AlcHlcStatusOfst; + + /* Confort Noise Mode. */ + tOCT6100_TLV_OFFSET ComfortNoiseModeOfst; + + /* NLP control field. */ + tOCT6100_TLV_OFFSET NlpControlFieldOfst; + + /* VAD control field offset.*/ + tOCT6100_TLV_OFFSET VadControlFieldOfst; + + /* NLP Trivial field offset. */ + tOCT6100_TLV_OFFSET NlpTrivialFieldOfst; + + /* Acoustic echo field offset. */ + tOCT6100_TLV_OFFSET AecFieldOfst; + + /* Acoustic echo default ERL field offset. */ + tOCT6100_TLV_OFFSET AecDefaultErlFieldOfst; + + /* Non-linearity behavior A and B field offset. */ + tOCT6100_TLV_OFFSET PcmLeakFieldOfst; + tOCT6100_TLV_OFFSET NlpConvCapFieldOfst; + + /* Default ERL field offset. */ + tOCT6100_TLV_OFFSET DefaultErlFieldOfst; + + /* Tone Removal field offset.*/ + tOCT6100_TLV_OFFSET ToneRemovalFieldOfst; + + + + /* Channel config fields offset. */ + tOCT6100_TLV_OFFSET ChanMainIoMaxEchoPointOfst; + tOCT6100_TLV_OFFSET TailDisplEnableOfst; + + /* Pouch fields offset. */ + tOCT6100_TLV_OFFSET PouchBootInstructionOfst; + tOCT6100_TLV_OFFSET PouchBootResultOfst; + tOCT6100_TLV_OFFSET PouchTailDisplOfst; + + /* 2100 Hz Auto disabling fields offset. */ + tOCT6100_TLV_OFFSET ToneDisablerControlOfst; + + /* Conferencing dominant speaker field offset. */ + tOCT6100_TLV_OFFSET DominantSpeakerFieldOfst; + + /* Conferencing noise reduction field offset. */ + tOCT6100_TLV_OFFSET ConferencingNoiseReductionOfst; + + /* Per channel tail displacement field offset. */ + tOCT6100_TLV_OFFSET PerChanTailDisplacementFieldOfst; + + /* Per channel tail length field offset. */ + tOCT6100_TLV_OFFSET PerChanTailLengthFieldOfst; + + /* AF control/echo cancellation bypass. */ + tOCT6100_TLV_OFFSET AftControlOfst; + + /* Voice detected stat field offset. */ + tOCT6100_TLV_OFFSET SinVoiceDetectedStatOfst; + + /* Rin currently applied gain field offset. */ + tOCT6100_TLV_OFFSET RinAppliedGainStatOfst; + + /* Sout currently applied gain field offset. */ + tOCT6100_TLV_OFFSET SoutAppliedGainStatOfst; + + /* Adaptive listener enhancement field offset. */ + tOCT6100_TLV_OFFSET AdaptiveAleOfst; + + /* Rin NR field offset. */ + tOCT6100_TLV_OFFSET RinAnrOfst; + + /* Rin NR value field offset. */ + tOCT6100_TLV_OFFSET RinAnrValOfst; + + /* Sin Mute field offset. */ + tOCT6100_TLV_OFFSET SinMuteOfst; + + /* Rin Mute field offset. */ + tOCT6100_TLV_OFFSET RinMuteOfst; + + /* Sout ANR SNR enhancement offset. */ + tOCT6100_TLV_OFFSET AnrSnrEnhancementOfst; + + /* Sout ANR voice-noise segregation offset. */ + tOCT6100_TLV_OFFSET AnrVoiceNoiseSegregationOfst; + + /* Tone disabler VQE activation delay offset. */ + tOCT6100_TLV_OFFSET ToneDisablerVqeActivationDelayOfst; + + /* AF tail displacement value configuration offset. */ + tOCT6100_TLV_OFFSET AfTailDisplacementFieldOfst; + + /* Pouch counter field offset. */ + tOCT6100_TLV_OFFSET PouchCounterFieldOfst; + + /* Acoustic echo tail length. */ + tOCT6100_TLV_OFFSET AecTailLengthFieldOfst; + + /* Is ISR called field offset. */ + tOCT6100_TLV_OFFSET IsIsrCalledFieldOfst; + + /* Music protection enable field offset. */ + tOCT6100_TLV_OFFSET MusicProtectionFieldOfst; + + /* Rin port energy level statistics field offset. */ + tOCT6100_TLV_OFFSET RinEnergyStatFieldOfst; + + /* Sout port energy level statistics field offset. */ + tOCT6100_TLV_OFFSET SoutEnergyStatFieldOfst; + + /* Double talk behavior field offset. */ + tOCT6100_TLV_OFFSET DoubleTalkBehaviorFieldOfst; + + /* Idle code detection field offset. */ + tOCT6100_TLV_OFFSET IdleCodeDetectionFieldOfst; + + /* TSI memory mapping information.*/ + UINT32 ulNumTsiEntries; + + /*-----------------------------------------------------------------------------*/ + +} tOCT6100_API_MEMORY_MAP, *tPOCT6100_API_MEMORY_MAP; + +typedef struct _OCT6100_API_SOFT_BUFS_ +{ + /* To avoid compilation errors. */ + UINT32 ulDummyVariable; + + /* Tone events buffer pointers. */ + UINT32 ulToneEventBufferWritePtr; + UINT32 ulToneEventBufferReadPtr; + UINT32 ulToneEventBufferSize; + UINT32 ulToneEventBufferMemOfst; + UINT32 ulToneEventBufferOverflowCnt; + + /* Playout events buffer pointers. */ + UINT32 ulBufPlayoutEventBufferWritePtr; + UINT32 ulBufPlayoutEventBufferReadPtr; + UINT32 ulBufPlayoutEventBufferSize; + UINT32 ulBufPlayoutEventBufferMemOfst; + UINT32 ulBufPlayoutEventBufferOverflowCnt; + +} tOCT6100_API_SOFT_BUFS, *tPOCT6100_API_SOFT_BUFS; + +typedef struct _OCT6100_API_IMAGE_REGION_ +{ + UINT32 ulPart1Size; + UINT32 ulPart2Size; + UINT32 ulClockInfo; + + UINT32 ulReserved; + + UINT32 ulPart1BaseAddress; + UINT32 ulPart2BaseAddress; + +} tOCT6100_API_IMAGE_REGION, *tPOCT6100_API_IMAGE_REGION; + +typedef struct _OCT6100_API_IMAGE_INFO_ +{ + UINT8 fBufferPlayout; + UINT8 fAdaptiveNoiseReduction; + UINT8 fRinDcOffsetRemoval; + UINT8 fSinDcOffsetRemoval; + + UINT8 fRinAutoLevelControl; + UINT8 fSoutAutoLevelControl; + UINT8 fRinHighLevelCompensation; + UINT8 fSoutHighLevelCompensation; + + UINT8 fAlcHlcStatus; + UINT8 fComfortNoise; + UINT8 fNlpControl; + UINT8 fSilenceSuppression; + + UINT8 fToneDisabler; + UINT8 fTailDisplacement; + UINT8 fPerChannelTailDisplacement; + UINT8 fAcousticEcho; + + UINT8 fAecEnabled; + UINT8 fToneRemoval; + UINT8 fDefaultErl; + UINT8 fMaxEchoPoint; + + UINT8 fNonLinearityBehaviorA; + UINT8 fNonLinearityBehaviorB; + UINT8 fAecDefaultErl; + UINT8 fAdpcm; + + UINT8 fConferencing; + UINT8 fConferencingNoiseReduction; + UINT8 fMusicProtection; + UINT8 fDominantSpeakerEnabled; + + UINT8 fAftControl; + UINT8 fSinVoiceDetectedStat; + UINT8 fRinAppliedGainStat; + UINT8 fSoutAppliedGainStat; + + UINT8 fListenerEnhancement; + UINT8 fRoutNoiseReduction; + UINT8 fRoutNoiseReductionLevel; + UINT8 fRinMute; + UINT8 fSinMute; + + UINT8 fAnrSnrEnhancement; + UINT8 fAnrVoiceNoiseSegregation; + UINT8 fRinBufferPlayoutHardSkip; + UINT8 fSoutBufferPlayoutHardSkip; + + UINT16 usMaxNumberOfChannels; + UINT8 fPerChannelTailLength; + UINT8 fToneDisablerVqeActivationDelay; + + UINT32 ulToneProfileNumber; + + UINT16 usMaxTailDisplacement; + UINT16 usMaxTailLength; + + UINT8 byNumToneDetectors; + UINT8 byMaxNumberPlayoutEvents; + + UINT8 fAfTailDisplacement; + UINT8 fAecTailLength; + + UINT8 fMusicProtectionConfiguration; + UINT8 byImageType; + + UINT8 fBufferPlayoutSkipInEvents; + UINT8 fSoutNoiseBleaching; + + UINT8 fRinEnergyStat; + UINT8 fSoutEnergyStat; + + UINT8 fDoubleTalkBehavior; + UINT8 fDoubleTalkBehaviorFieldOfst; + + UINT8 fIdleCodeDetection; + UINT8 fIdleCodeDetectionConfiguration; + + UINT8 fSinLevel; + + + + UINT8 szVersionNumber[ cOCT6100_VERSION_NUMBER_MAX_SIZE ]; + UINT32 ulBuildId; + + tOCT6100_TLV_TONE_INFO aToneInfo[ cOCT6100_MAX_TONE_EVENT ]; + +} tOCT6100_API_IMAGE_INFO, *tPOCT6100_API_IMAGE_INFO; + +typedef struct _OCT6100_API_MIXER_ +{ + /* Pointer to the various event region. */ + UINT16 usFirstSoutCopyEventPtr; + UINT16 usLastSoutCopyEventPtr; + + UINT16 usFirstBridgeEventPtr; + UINT16 usLastBridgeEventPtr; + + UINT16 usFirstSinCopyEventPtr; + UINT16 usLastSinCopyEventPtr; + + /* Recording event info. */ + UINT16 usRecordCopyEventIndex; + UINT16 usRecordSinEventIndex; + +} tOCT6100_API_MIXER, tPOCT6100_API_MIXER; + + +typedef struct _OCT6100_API_BUFFER_PLAYOUT_MALLOC_INFO_ +{ + /* Next node to be checked for free memory. */ + UINT32 ulRovingNode; + + /* First unused node in the unused list. */ + UINT32 ulFirstUnusedNode; + + /* Last unused node in the unused list. */ + UINT32 ulLastUnusedNode; + + /* Count of unused nodes. */ + UINT32 ulUnusedNodeCnt; + +} tOCT6100_API_BUFFER_PLAYOUT_MALLOC_INFO, *tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_INFO; + + + + +#endif /* __OCT6100_CHIP_OPEN_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_chip_open_pub.h b/xpp/oct612x/include/oct6100api/oct6100_chip_open_pub.h new file mode 100644 index 0000000..7153106 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_chip_open_pub.h @@ -0,0 +1,241 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_open_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_chip_open.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_chip_open_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 54 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHIP_OPEN_PUB_H__ +#define __OCT6100_CHIP_OPEN_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_CHIP_OPEN_ +{ + UINT32 ulUserChipId; + BOOL fMultiProcessSystem; + PVOID pProcessContext; + + UINT32 ulMaxRwAccesses; + + unsigned char const *pbyImageFile; /* Byte pointer to the image file to be uploaded into the chip. */ + UINT32 ulImageSize; /* Size of the image file (in bytes). */ + + UINT32 ulMemClkFreq; /* 10 - 133.3 MHz. */ + UINT32 ulUpclkFreq; /* 1 - 66.6 MHz. */ + BOOL fEnableMemClkOut; + + UINT32 ulMemoryType; /* SDRAM or DDR type external memory. */ + UINT32 ulNumMemoryChips; /* Number of memory chips present. */ + UINT32 ulMemoryChipSize; /* The size of the memory chips. */ + + UINT32 ulTailDisplacement; /* Tail displacement supported by the chip. */ + + BOOL fEnableAcousticEcho;/* Acoustic echo cancellation enabled. */ + + /* Resource allocation parameters. */ + UINT32 ulMaxChannels; + UINT32 ulMaxTsiCncts; + UINT32 ulMaxBiDirChannels; + UINT32 ulMaxConfBridges; + UINT32 ulMaxFlexibleConfParticipants; + UINT32 ulMaxPlayoutBuffers; + + + UINT32 ulMaxPhasingTssts; + UINT32 ulMaxAdpcmChannels; + BOOL fUseSynchTimestamp; + UINT32 aulTimestampTimeslots[ 4 ]; + UINT32 aulTimestampStreams[ 4 ]; + UINT32 ulInterruptPolarity; + tOCT6100_INTERRUPT_CONFIGURE InterruptConfig; + + UINT32 aulTdmStreamFreqs[ cOCT6100_TDM_STREAM_MAX_GROUPS ]; + UINT32 ulMaxTdmStreams; + UINT32 ulTdmSampling; + + BOOL fEnableFastH100Mode; + + UINT32 ulSoftToneEventsBufSize; /* In events. */ + BOOL fEnableExtToneDetection; + BOOL fEnable2100StopEvent; + + + UINT32 ulSoftBufferPlayoutEventsBufSize; /* In events. */ + UINT32 ulMaxRemoteDebugSessions; + + BOOL fEnableChannelRecording; + + BOOL fEnableProductionBist; + UINT32 ulProductionBistMode; + UINT32 ulNumProductionBistLoops; + +} tOCT6100_CHIP_OPEN, *tPOCT6100_CHIP_OPEN; + +typedef struct _OCT6100_GET_INSTANCE_SIZE_ +{ + UINT32 ulApiInstanceSize; + +} tOCT6100_GET_INSTANCE_SIZE, *tPOCT6100_GET_INSTANCE_SIZE; + +typedef struct _OCT6100_CHIP_CLOSE_ +{ + UINT32 ulDummyVariable; + +} tOCT6100_CHIP_CLOSE, *tPOCT6100_CHIP_CLOSE; + +typedef struct _OCT6100_CREATE_LOCAL_INSTANCE_ +{ + tPOCT6100_INSTANCE_API pApiInstShared; + tPOCT6100_INSTANCE_API pApiInstLocal; + PVOID pProcessContext; + UINT32 ulUserChipId; + +} tOCT6100_CREATE_LOCAL_INSTANCE, *tPOCT6100_CREATE_LOCAL_INSTANCE; + +typedef struct _OCT6100_DESTROY_LOCAL_INSTANCE_ +{ + UINT32 ulDummy; + +} tOCT6100_DESTROY_LOCAL_INSTANCE, *tPOCT6100_DESTROY_LOCAL_INSTANCE; + +typedef struct _OCT6100_GET_HW_REVISION_ +{ + UINT32 ulUserChipId; + PVOID pProcessContext; + UINT32 ulRevisionNum; + +} tOCT6100_GET_HW_REVISION, *tPOCT6100_GET_HW_REVISION; + +typedef struct _OCT6100_FREE_RESOURCES_ +{ + BOOL fFreeTsiConnections; + BOOL fFreeConferenceBridges; + BOOL fFreePlayoutBuffers; + BOOL fFreePhasingTssts; + BOOL fFreeAdpcmChannels; + +} tOCT6100_FREE_RESOURCES, *tPOCT6100_FREE_RESOURCES; + +typedef struct _OCT6100_PRODUCTION_BIST_ +{ + UINT32 ulCurrentAddress; + UINT32 ulCurrentLoop; + UINT32 ulCurrentTest; + UINT32 ulBistStatus; + UINT32 ulFailedAddress; + UINT32 ulReadValue; + UINT32 ulExpectedValue; + +} tOCT6100_PRODUCTION_BIST, *tPOCT6100_PRODUCTION_BIST; + +typedef struct _OCT6100_API_GET_VERSION_ +{ + UINT8 achApiVersion[ cOCT6100_API_VERSION_STRING_LENGTH ]; + +} tOCT6100_API_GET_VERSION, *tPOCT6100_API_GET_VERSION; + +typedef struct _OCT6100_API_GET_CAPACITY_PINS_ +{ + UINT32 ulUserChipId; + PVOID pProcessContext; + UINT32 ulMemoryType; /* SDRAM or DDR type external memory. */ + BOOL fEnableMemClkOut; + UINT32 ulMemClkFreq; + UINT32 ulCapacityValue; +} tOCT6100_API_GET_CAPACITY_PINS, *tPOCT6100_API_GET_CAPACITY_PINS; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ChipOpenDef( + OUT tPOCT6100_CHIP_OPEN f_pChipOpen ); +UINT32 Oct6100ChipOpen( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHIP_OPEN f_pChipOpen ); + +UINT32 Oct6100ChipCloseDef( + OUT tPOCT6100_CHIP_CLOSE f_pChipClose ); +UINT32 Oct6100ChipClose( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHIP_CLOSE f_pChipClose ); + +UINT32 Oct6100GetInstanceSizeDef( + OUT tPOCT6100_GET_INSTANCE_SIZE f_pInstanceSize ); +UINT32 Oct6100GetInstanceSize( + IN OUT tPOCT6100_CHIP_OPEN f_pChipOpen, + IN OUT tPOCT6100_GET_INSTANCE_SIZE f_pInstanceSize ); + +UINT32 Oct6100CreateLocalInstanceDef( + OUT tPOCT6100_CREATE_LOCAL_INSTANCE f_pCreateLocal ); +UINT32 Oct6100CreateLocalInstance( + IN OUT tPOCT6100_CREATE_LOCAL_INSTANCE f_pCreateLocal ); + +UINT32 Oct6100DestroyLocalInstanceDef( + OUT tPOCT6100_DESTROY_LOCAL_INSTANCE f_pDestroyLocal ); +UINT32 Oct6100DestroyLocalInstance( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_DESTROY_LOCAL_INSTANCE f_pDestroyLocal ); + +UINT32 Oct6100ApiGetVersionDef( + OUT tPOCT6100_API_GET_VERSION f_pApiGetVersion ); +UINT32 Oct6100ApiGetVersion( + IN OUT tPOCT6100_API_GET_VERSION f_pApiGetVersion ); + +UINT32 Oct6100GetHwRevisionDef( + OUT tPOCT6100_GET_HW_REVISION f_pRevision ); +UINT32 Oct6100GetHwRevision( + IN OUT tPOCT6100_GET_HW_REVISION f_pRevision ); + +UINT32 Oct6100FreeResourcesDef( + OUT tPOCT6100_FREE_RESOURCES f_pFreeResources ); +UINT32 Oct6100FreeResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_FREE_RESOURCES f_pFreeResources ); + +UINT32 Oct6100ProductionBistDef( + OUT tPOCT6100_PRODUCTION_BIST f_pProductionBist ); +UINT32 Oct6100ProductionBist( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PRODUCTION_BIST f_pProductionBist ); + +UINT32 Oct6100ApiGetCapacityPinsDef( + tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins); + +UINT32 Oct6100ApiGetCapacityPins( + tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins ); + + +#endif /* __OCT6100_CHIP_OPEN_PUB_H__ */ + diff --git a/xpp/oct612x/include/oct6100api/oct6100_chip_stats_inst.h b/xpp/oct612x/include/oct6100api/oct6100_chip_stats_inst.h new file mode 100644 index 0000000..bcba616 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_chip_stats_inst.h @@ -0,0 +1,84 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_stats_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_chip_stats.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_chip_stats_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 21 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHIP_STATS_INST_H__ +#define __OCT6100_CHIP_STATS_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_CHIP_ERROR_STATS_ +{ + UINT8 fFatalChipError; + + UINT32 ulInternalReadTimeoutCnt; + UINT32 ulSdramRefreshTooLateCnt; + UINT32 ulPllJitterErrorCnt; + + /* Internal tone detector error counter. */ + UINT32 ulToneDetectorErrorCnt; + + UINT32 ulOverflowToneEventsCnt; + + UINT32 ulH100OutOfSyncCnt; + UINT32 ulH100ClkABadCnt; + UINT32 ulH100ClkBBadCnt; + UINT32 ulH100FrameABadCnt; + + + +} tOCT6100_API_CHIP_ERROR_STATS, *tPOCT6100_API_CHIP_ERROR_STATS; + +typedef struct _OCT6100_API_CHIP_STATS_ +{ + UINT16 usNumberChannels; + UINT16 usNumberBiDirChannels; + UINT16 usNumberTsiCncts; + UINT16 usNumberConfBridges; + UINT16 usNumberPlayoutBuffers; + UINT16 usNumEcChanUsingMixer; + + UINT32 ulPlayoutMemUsed; + UINT16 usNumberActiveBufPlayoutPorts; + + UINT16 usNumberPhasingTssts; + UINT16 usNumberAdpcmChans; + +} tOCT6100_API_CHIP_STATS, *tPOCT6100_API_CHIP_STATS; + +#endif /* __OCT6100_CHIP_STATS_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_chip_stats_pub.h b/xpp/oct612x/include/oct6100api/oct6100_chip_stats_pub.h new file mode 100644 index 0000000..a718f7b --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_chip_stats_pub.h @@ -0,0 +1,150 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_stats_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_chip_stats.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_chip_stats_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 59 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHIP_STATS_PUB_H__ +#define __OCT6100_CHIP_STATS_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_CHIP_STATS_ +{ + BOOL fResetChipStats; + + UINT32 ulNumberChannels; + UINT32 ulNumberTsiCncts; + UINT32 ulNumberConfBridges; + UINT32 ulNumberPlayoutBuffers; + UINT32 ulPlayoutFreeMemSize; + UINT32 ulNumberPhasingTssts; + UINT32 ulNumberAdpcmChannels; + + UINT32 ulH100OutOfSynchCount; + UINT32 ulH100ClockABadCount; + UINT32 ulH100FrameABadCount; + UINT32 ulH100ClockBBadCount; + + UINT32 ulInternalReadTimeoutCount; + UINT32 ulSdramRefreshTooLateCount; + UINT32 ulPllJitterErrorCount; + + UINT32 ulOverflowToneEventsCount; + UINT32 ulSoftOverflowToneEventsCount; + + UINT32 ulSoftOverflowBufferPlayoutEventsCount; + +} tOCT6100_CHIP_STATS, *tPOCT6100_CHIP_STATS; + +typedef struct _OCT6100_CHIP_TONE_INFO_ +{ + UINT32 ulToneID; + UINT32 ulDetectionPort; + + UINT8 aszToneName[ cOCT6100_TLV_MAX_TONE_NAME_SIZE ]; + +} tOCT6100_CHIP_TONE_INFO, *tPOCT6100_CHIP_TONE_INFO; + +typedef struct _OCT6100_CHIP_IMAGE_INFO_ +{ + BOOL fBufferPlayout; + BOOL fAdaptiveNoiseReduction; + BOOL fSoutNoiseBleaching; + BOOL fAutoLevelControl; + BOOL fHighLevelCompensation; + BOOL fSilenceSuppression; + + BOOL fAdpcm; + BOOL fConferencing; + BOOL fConferencingNoiseReduction; + BOOL fDominantSpeaker; + + BOOL fAcousticEcho; + BOOL fAecTailLength; + BOOL fToneRemoval; + + BOOL fDefaultErl; + BOOL fNonLinearityBehaviorA; + BOOL fNonLinearityBehaviorB; + BOOL fPerChannelTailDisplacement; + BOOL fPerChannelTailLength; + BOOL fListenerEnhancement; + BOOL fRoutNoiseReduction; + BOOL fRoutNoiseReductionLevel; + BOOL fAnrSnrEnhancement; + BOOL fAnrVoiceNoiseSegregation; + BOOL fToneDisablerVqeActivationDelay; + BOOL fMusicProtection; + BOOL fDoubleTalkBehavior; + BOOL fIdleCodeDetection; + BOOL fSinLevel; + + UINT32 ulMaxChannels; + UINT32 ulNumTonesAvailable; + UINT32 ulToneProfileNumber; + UINT32 ulMaxTailDisplacement; + UINT32 ulMaxTailLength; + UINT32 ulDebugEventSize; + UINT32 ulMaxPlayoutEvents; + + UINT32 ulImageType; + + UINT8 szVersionNumber[ cOCT6100_VERSION_NUMBER_MAX_SIZE ]; + UINT32 ulBuildId; + + tOCT6100_CHIP_TONE_INFO aToneInfo[ cOCT6100_MAX_TONE_EVENT ]; + +} tOCT6100_CHIP_IMAGE_INFO, *tPOCT6100_CHIP_IMAGE_INFO; + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ChipGetStatsDef( + OUT tPOCT6100_CHIP_STATS f_pChipStats ); + +UINT32 Oct6100ChipGetStats( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_CHIP_STATS f_pChipStats ); + +UINT32 Oct6100ChipGetImageInfoDef( + OUT tPOCT6100_CHIP_IMAGE_INFO f_pChipImageInfo ); + +UINT32 Oct6100ChipGetImageInfo( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + OUT tPOCT6100_CHIP_IMAGE_INFO f_pChipImageInfo ); + +#endif /* __OCT6100_CHIP_STATS_PUB_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_conf_bridge_inst.h b/xpp/oct612x/include/oct6100api/oct6100_conf_bridge_inst.h new file mode 100644 index 0000000..f49a473 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_conf_bridge_inst.h @@ -0,0 +1,104 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_conf_bridge_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_conf_bridge.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_conf_bridge_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 19 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CONF_BRIDGE_INST_H__ +#define __OCT6100_CONF_BRIDGE_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_CONF_BRIDGE_ +{ + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Entry counter for the resources. */ + UINT8 byEntryOpenCnt; + + /* Next bridge pointer. */ + UINT16 usNextBridgePtr; + + /* Previous bridge pointer. */ + UINT16 usPrevBridgePtr; + + /* Number of clients connected to the bridge. */ + UINT16 usNumClients; + + /* Store the index of the load event, to diffentiate him form the accumulate. */ + UINT16 usLoadIndex; + + /* Pointer to the first bridge events.*/ + UINT16 usFirstLoadEventPtr; + UINT16 usFirstSubStoreEventPtr; + UINT16 usLastSubStoreEventPtr; + + /* Pointer to the silence load event, if it exists. */ + UINT16 usSilenceLoadEventPtr; + + /* Flag specifying whether the dominant speaker is set or not. */ + UINT16 usDominantSpeakerChanIndex; + UINT8 fDominantSpeakerSet; + + /* Flag specifying if this is flexible conferencing bridge. */ + UINT8 fFlexibleConferencing; + + /* Number of clients being tapped. */ + UINT16 usNumTappedClients; + +} tOCT6100_API_CONF_BRIDGE, *tPOCT6100_API_CONF_BRIDGE; + +typedef struct _OCT6100_API_FLEX_CONF_PARTICIPANT_ +{ + /* Input port of the conferencing for this participant. */ + UINT32 ulInputPort; + + /* Whether the flexible mixer has been created. */ + UINT8 fFlexibleMixerCreated; + + /* Listener mask ( who can hear us ). */ + UINT32 ulListenerMask; + + /* Our index in the listener mask. */ + UINT32 ulListenerMaskIndex; + + /* Mixer event indexes for this participant's mixer. */ + UINT16 ausLoadOrAccumulateEventIndex[ cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE ]; + +} tOCT6100_API_FLEX_CONF_PARTICIPANT, *tPOCT6100_API_FLEX_CONF_PARTICIPANT; + +#endif /* __OCT6100_CONF_BRIDGE_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_conf_bridge_pub.h b/xpp/oct612x/include/oct6100api/oct6100_conf_bridge_pub.h new file mode 100644 index 0000000..4ecea7b --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_conf_bridge_pub.h @@ -0,0 +1,169 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_conf_bridge_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_conf_bridge.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_conf_bridge_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 22 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CONF_BRIDGE_PUB_H__ +#define __OCT6100_CONF_BRIDGE_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_CONF_BRIDGE_OPEN_ +{ + PUINT32 pulConfBridgeHndl; /* Handle returned when the bridge is opened. */ + BOOL fFlexibleConferencing; + +} tOCT6100_CONF_BRIDGE_OPEN, *tPOCT6100_CONF_BRIDGE_OPEN; + +typedef struct _OCT6100_CONF_BRIDGE_CLOSE_ +{ + UINT32 ulConfBridgeHndl; + +} tOCT6100_CONF_BRIDGE_CLOSE, *tPOCT6100_CONF_BRIDGE_CLOSE; + +typedef struct _OCT6100_CONF_BRIDGE_CHAN_ADD_ +{ + UINT32 ulConfBridgeHndl; + UINT32 ulChannelHndl; + UINT32 ulInputPort; + UINT32 ulListenerMaskIndex; + UINT32 ulListenerMask; + BOOL fMute; + UINT32 ulTappedChannelHndl; + +} tOCT6100_CONF_BRIDGE_CHAN_ADD, *tPOCT6100_CONF_BRIDGE_CHAN_ADD; + +typedef struct _OCT6100_CONF_BRIDGE_CHAN_REMOVE_ +{ + UINT32 ulConfBridgeHndl; + UINT32 ulChannelHndl; + BOOL fRemoveAll; + +} tOCT6100_CONF_BRIDGE_CHAN_REMOVE, *tPOCT6100_CONF_BRIDGE_CHAN_REMOVE; + +typedef struct _OCT6100_CONF_BRIDGE_CHAN_MUTE_ +{ + UINT32 ulChannelHndl; + +} tOCT6100_CONF_BRIDGE_CHAN_MUTE, *tPOCT6100_CONF_BRIDGE_CHAN_MUTE; + +typedef struct _OCT6100_CONF_BRIDGE_CHAN_UNMUTE_ +{ + UINT32 ulChannelHndl; + +} tOCT6100_CONF_BRIDGE_CHAN_UNMUTE, *tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE; + +typedef struct _OCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET_ +{ + UINT32 ulConfBridgeHndl; + UINT32 ulChannelHndl; + +} tOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET, *tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET; + +typedef struct _OCT6100_CONF_BRIDGE_MASK_CHANGE_ +{ + UINT32 ulChannelHndl; + UINT32 ulNewListenerMask; + +} tOCT6100_CONF_BRIDGE_MASK_CHANGE, *tPOCT6100_CONF_BRIDGE_MASK_CHANGE; + +typedef struct _OCT6100_CONF_BRIDGE_STATS_ +{ + UINT32 ulConfBridgeHndl; + UINT32 ulNumChannels; + UINT32 ulNumTappedChannels; + BOOL fFlexibleConferencing; + +} tOCT6100_CONF_BRIDGE_STATS, *tPOCT6100_CONF_BRIDGE_STATS; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ConfBridgeOpenDef( + OUT tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ); +UINT32 Oct6100ConfBridgeOpen( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ); + +UINT32 Oct6100ConfBridgeCloseDef( + OUT tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose ); +UINT32 Oct6100ConfBridgeClose( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose ); + +UINT32 Oct6100ConfBridgeChanAddDef( + OUT tPOCT6100_CONF_BRIDGE_CHAN_ADD f_pConfBridgeAdd ); +UINT32 Oct6100ConfBridgeChanAdd( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_CHAN_ADD f_pConfBridgeAdd ); + +UINT32 Oct6100ConfBridgeChanRemoveDef( + OUT tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove ); +UINT32 Oct6100ConfBridgeChanRemove( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove ); + +UINT32 Oct6100ConfBridgeChanMuteDef( + OUT tPOCT6100_CONF_BRIDGE_CHAN_MUTE f_pConfBridgeMute ); +UINT32 Oct6100ConfBridgeChanMute( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_CHAN_MUTE f_pConfBridgeMute ); + +UINT32 Oct6100ConfBridgeChanUnMuteDef( + OUT tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE f_pConfBridgeUnMute ); +UINT32 Oct6100ConfBridgeChanUnMute( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE f_pConfBridgeUnMute ); + +UINT32 Oct6100ConfBridgeDominantSpeakerSetDef( + OUT tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET f_pConfBridgeDominantSpeaker ); +UINT32 Oct6100ConfBridgeDominantSpeakerSet( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET f_pConfBridgeDominantSpeaker ); + +UINT32 Oct6100ConfBridgeMaskChangeDef( + OUT tPOCT6100_CONF_BRIDGE_MASK_CHANGE f_pConfBridgeMaskChange ); +UINT32 Oct6100ConfBridgeMaskChange( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_MASK_CHANGE f_pConfBridgeMaskChange ); + +UINT32 Oct6100ConfBridgeGetStatsDef( + OUT tPOCT6100_CONF_BRIDGE_STATS f_pConfBridgeStats ); +UINT32 Oct6100ConfBridgeGetStats( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_STATS f_pConfBridgeStats ); + +#endif /* __OCT6100_CONF_BRIDGE_PUB_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_debug_inst.h b/xpp/oct612x/include/oct6100api/oct6100_debug_inst.h new file mode 100644 index 0000000..6a6f573 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_debug_inst.h @@ -0,0 +1,124 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_debug_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_debug.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_debug_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 10 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_DEBUG_INST_H__ +#define __OCT6100_DEBUG_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_DEBUG_ +{ + /* Information from the TLVs. */ + UINT32 ulDebugEventSize; + UINT32 ulMatrixBaseAddress; + UINT32 ulDebugChanStatsByteSize; + UINT32 ulDebugChanLiteStatsByteSize; + UINT32 ulHotChannelSelectBaseAddress; + UINT32 ulMatrixTimestampBaseAddress; + UINT32 ulAfWritePtrByteOffset; + UINT32 ulRecordedPcmEventByteSize; + UINT32 ulMatrixWpBaseAddress; + + /* Pouch counter presence in the image. */ + UINT8 fPouchCounter; + + /* Record channel indexes. */ + UINT16 usRecordMemIndex; + UINT16 usRecordChanIndex; + + UINT16 usRecordRinRoutTsiMemIndex; + UINT16 usRecordSinSoutTsiMemIndex; + + /* Debug channel information.*/ + UINT16 usCurrentDebugChanIndex; + + /* Matrix event mask. */ + UINT16 usMatrixCBMask; + + /* If data is being dumped now. */ + UINT8 fDebugDataBeingDumped; + + /* Index of the last event retrieved. */ + UINT16 usLastDebugEventIndex; + + /* Number of events to retrieve. */ + UINT16 usNumEvents; + + /* Chip debug event write ptr. */ + UINT16 usChipDebugEventWritePtr; + + /* Hot channel read data. */ + UINT16 ausHotChannelData[ 2 ]; + + /* Last PCM sample index. */ + UINT32 ulLastPcmSampleIndex; + + /* Last AF log read pointer. */ + UINT16 usLastAfLogReadPtr; + + /* AF log hardware write pointer. */ + UINT16 usAfLogWritePtr; + + /* Last tone event index retrieved. */ + UINT16 usLastToneEventIndex; + + /* Whether the image version string has been copied in the user buffer. */ + BOOL fImageVersionCopied; + + /* Whether the api version string has been copied in the user buffer. */ + BOOL fApiVersionCopied; + + /* Total number of bytes that will be returned for the current dump. */ + UINT32 ulDebugDataTotalNumBytes; + + /* Field to detect if the ISR is called present? */ + BOOL fIsIsrCalledField; + + /* Remaining number of bytes that will be returned for the current dump. */ + UINT32 ulDebugDataRemainingNumBytes; + + /* AF events control block size. */ + UINT32 ulAfEventCbByteSize; + + /* Current user selected data mode. Must be kept constant throughout a debug session. */ + UINT32 ulCurrentGetDataMode; + +} tOCT6100_API_DEBUG, *tPOCT6100_API_DEBUG; + +#endif /* __OCT6100_DEBUG_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_debug_pub.h b/xpp/oct612x/include/oct6100api/oct6100_debug_pub.h new file mode 100644 index 0000000..097ecc6 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_debug_pub.h @@ -0,0 +1,76 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_debug_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_debug.c. All elements defined in this file are for public + usage of the API. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 14 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_DEBUG_PUB_H__ +#define __OCT6100_DEBUG_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_DEBUG_SELECT_CHANNEL_ +{ + UINT32 ulChannelHndl; + +} tOCT6100_DEBUG_SELECT_CHANNEL, *tPOCT6100_DEBUG_SELECT_CHANNEL; + +typedef struct _OCT6100_DEBUG_GET_DATA_ +{ + UINT32 ulGetDataMode; + UINT32 ulGetDataContent; + UINT32 ulRemainingNumBytes; + UINT32 ulTotalNumBytes; + UINT32 ulMaxBytes; + UINT32 ulValidNumBytes; + PUINT8 pbyData; + +} tOCT6100_DEBUG_GET_DATA, *tPOCT6100_DEBUG_GET_DATA; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100DebugSelectChannelDef( + OUT tPOCT6100_DEBUG_SELECT_CHANNEL f_pSelectDebugChan ); +UINT32 Oct6100DebugSelectChannel( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_DEBUG_SELECT_CHANNEL f_pSelectDebugChan ); + +UINT32 Oct6100DebugGetDataDef( + OUT tPOCT6100_DEBUG_GET_DATA f_pGetData ); +UINT32 Oct6100DebugGetData( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_DEBUG_GET_DATA f_pGetData ); + +#endif /* __OCT6100_DEBUG_PUB_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_defines.h b/xpp/oct612x/include/oct6100api/oct6100_defines.h new file mode 100644 index 0000000..ef12119 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_defines.h @@ -0,0 +1,679 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_defines.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Header file containing all defines used throughout the API. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.7 + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 171 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_DEFINES_H__ +#define __OCT6100_DEFINES_H__ + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +/***************************** DEFINES *************************************/ + +/* 32-bits values. */ +#define cOCT6100_FFFFFFFF 0xFFFFFFFF +#define cOCT6100_FFFFFFFE 0xFFFFFFFE +#define cOCT6100_7FFFFFFF 0x7FFFFFFF + +/* 16-bits values. */ +#define cOCT6100_FFFD 0xFFFD +#define cOCT6100_FFFE 0xFFFE +#define cOCT6100_FFFF 0xFFFF +#define cOCT6100_7FFF 0x7FFF + +/* 8-bits values. */ +#define cOCT6100_FF 0xFF + +#define cOCT6100_CURRENT_VALUE cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_CHIP_ID cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_HANDLE cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_TIMESLOT cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_STREAM cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_VALUE cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_STAT cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_STAT_W cOCT6100_FFFF +#define cOCT6100_INVALID_PCM_LAW cOCT6100_FF +#define cOCT6100_INVALID_EVENT cOCT6100_FFFF +#define cOCT6100_INVALID_INDEX cOCT6100_FFFF +#define cOCT6100_INVALID_TONE cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_PORT cOCT6100_FF + +#define cOCT6100_AUTO_SELECT cOCT6100_FFFFFFFE +#define cOCT6100_AUTO_SELECT_TAIL cOCT6100_FFFE + +#define cOCT6100_INVALID_BOOL 2 + +#define cOCT6100_KEEP_PREVIOUS_SETTING 0x70100000 + +#define cOCT6100_INVALID_SIGNED_STAT cOCT6100_7FFFFFFF +#define cOCT6100_INVALID_SIGNED_STAT_W cOCT6100_7FFF +#define cOCT6100_INVALID_ECHO_DELAY 0x400 + + + +#define cOCT6100_SIZE_128 128 +#define cOCT6100_SIZE_256 256 +#define cOCT6100_SIZE_512 512 +#define cOCT6100_SIZE_1K 1024 +#define cOCT6100_SIZE_2K 2048 +#define cOCT6100_SIZE_4K 4096 +#define cOCT6100_SIZE_8K 8192 +#define cOCT6100_SIZE_16K 16384 +#define cOCT6100_SIZE_32K 32768 +#define cOCT6100_SIZE_64K 65536 +#define cOCT6100_SIZE_128K 131072 +#define cOCT6100_SIZE_256K 262144 +#define cOCT6100_SIZE_512K 524288 +#define cOCT6100_SIZE_1M 1048576 +#define cOCT6100_SIZE_2M 2097152 +#define cOCT6100_SIZE_4M 4194304 +#define cOCT6100_SIZE_8M 8388608 +#define cOCT6100_SIZE_16M 16777216 +#define cOCT6100_SIZE_32M 33554432 +#define cOCT6100_SIZE_64M 67108864 +#define cOCT6100_SIZE_128M 134217728 +#define cOCT6100_SIZE_256M 268435456 +#define cOCT6100_SIZE_512M 536870912 +#define cOCT6100_SIZE_1G 1073741824 +#define cOCT6100_SIZE_2G 2147483648 + +#define cOCT6100_HNDL_TAG_MASK 0xFF000000 +#define cOCT6100_HNDL_INDEX_MASK 0x0000FFFF +#define cOCT6100_ENTRY_OPEN_CNT_MASK 0x000000FF +#define cOCT6100_ENTRY_OPEN_CNT_SHIFT 16 + +#define cOCT6100_HNDL_TAG_INVALID 0xFF000000 + +#define cOCT6100_HNDL_TAG_CHANNEL 0x01000000 +#define cOCT6100_HNDL_TAG_TSI_CNCT 0x02000000 +#define cOCT6100_HNDL_TAG_CONF_BRIDGE 0x03000000 +#define cOCT6100_HNDL_TAG_PHASING_TSST 0x04000000 +#define cOCT6100_HNDL_TAG_BIDIR_CHANNEL 0x05000000 +#define cOCT6100_HNDL_TAG_COPY_EVENT 0x06000000 +#define cOCT6100_HNDL_TAG_ADPCM_CHANNEL 0x07000000 + +#define cOCT6100_INVALID_HANDLE_TYPE cOCT6100_INVALID_VALUE + +#define cOCT6100_MEMORY_ROUND_SIZE 16 + +#define mOCT6100_ROUND_MEMORY_SIZE( ulMemorySize, ulTempVar ) \ + if ((ulTempVar = ulMemorySize % cOCT6100_MEMORY_ROUND_SIZE) != 0) \ + ulMemorySize += cOCT6100_MEMORY_ROUND_SIZE - ulTempVar; + +#define mOCT6100_ROUND_ADDRESS( ulAddress, ulBoundary, ulTempVar ) \ + if ((ulTempVar = ulAddress % ulBoundary) != 0) \ + ulAddress += ulBoundary - ulTempVar; + +#define cOCT6100_INTERNAL_CLOCK_SOURCE 0 +#define cOCT6100_EXTERNAL_CLOCK_SOURCE 1 + +#define cOCT6100_ACTIVE_HIGH_POLARITY 0 +#define cOCT6100_ACTIVE_LOW_POLARITY 1 + +#define cOCT6100_TDM_SAMPLE_AT_3_QUARTERS 0 +#define cOCT6100_TDM_SAMPLE_AT_RISING_EDGE 1 +#define cOCT6100_TDM_SAMPLE_AT_FALLING_EDGE 2 + +#define cOCT6100_TDM_STREAM_FREQ_2MHZ 0 +#define cOCT6100_TDM_STREAM_FREQ_4MHZ 1 +#define cOCT6100_TDM_STREAM_FREQ_8MHZ 2 +#define cOCT6100_TDM_STREAM_FREQ_16MHZ 3 + +#define cOCT6100_TDM_STREAM_MAX_GROUPS 8 + +#define cOCT6100_PCM_U_LAW 0 +#define cOCT6100_PCM_A_LAW 1 +#define cOCT6100_PCM_UNCHANGED 2 +#define cOCT6100_ADPCM_ENCODED 3 + +#define cOCT6100_INTERRUPT_DISABLE 0 +#define cOCT6100_INTERRUPT_NO_TIMEOUT 1 +#define cOCT6100_INTERRUPT_TIMEOUT 2 + +#define cOCT6100_NUMBER_TSSTS_1 1 +#define cOCT6100_NUMBER_TSSTS_2 2 + +#define cOCT6100_G711_64KBPS 1 +#define cOCT6100_G726_40KBPS 2 +#define cOCT6100_G726_32KBPS 3 +#define cOCT6100_G726_24KBPS 4 +#define cOCT6100_G726_16KBPS 5 +#define cOCT6100_G727_40KBPS_4_1 6 +#define cOCT6100_G727_40KBPS_3_2 7 +#define cOCT6100_G727_40KBPS_2_3 8 +#define cOCT6100_G727_32KBPS_4_0 9 +#define cOCT6100_G727_32KBPS_3_1 10 +#define cOCT6100_G727_32KBPS_2_2 11 +#define cOCT6100_G727_24KBPS_3_0 12 +#define cOCT6100_G727_24KBPS_2_1 13 +#define cOCT6100_G727_16KBPS_2_0 14 +#define cOCT6100_G726_ENCODED 15 +#define cOCT6100_G711_G726_ENCODED 16 +#define cOCT6100_G711_G727_2C_ENCODED 17 +#define cOCT6100_G711_G727_3C_ENCODED 18 +#define cOCT6100_G711_G727_4C_ENCODED 19 +#define cOCT6100_G727_2C_ENCODED 20 +#define cOCT6100_G727_3C_ENCODED 21 +#define cOCT6100_G727_4C_ENCODED 22 + +#define cOCT6100_ADPCM_IN_HIGH_BITS 0 +#define cOCT6100_ADPCM_IN_LOW_BITS 1 + +/* The values of these defines must not change. */ +#define cOCT6100_H100_TRACKA 0 +#define cOCT6100_H100_TRACKB 1 +#define cOCT6100_H100_TRACKA_FALLBACKB 2 +#define cOCT6100_H100_TRACKB_FALLBACKA 3 +#define cOCT6100_H100_DISABLED 4 +#define cOCT6100_H100_MASTERA 5 +#define cOCT6100_H100_BACKUPA 6 +#define cOCT6100_H100_MASTERB 7 +#define cOCT6100_H100_BACKUPB 8 + +#define cOCT6100_FREE_TSST 0 +#define cOCT6100_RX_TSST 16 +#define cOCT6100_TX_TSST 32 + +#define cOCT6100_INTRPT_ACTIVE 0 +#define cOCT6100_INTRPT_WILL_TIMEOUT 1 +#define cOCT6100_INTRPT_IN_TIMEOUT 2 +#define cOCT6100_INTRPT_DISABLED 3 + +#define cOCT6100_EXTERNAL_MEM_BIST_TIMEOUT 1000000 + +/* Clocks defines */ +#define cOCT6100_UPCLK_FREQ_33_33_MHZ 33333333 + +#define cOCT6100_MCLK_FREQ_133_MHZ 133000000 +#define cOCT6100_MCLK_FREQ_125_MHZ 125000000 +#define cOCT6100_MCLK_FREQ_117_MHZ 117000000 +#define cOCT6100_MCLK_FREQ_108_MHZ 108000000 +#define cOCT6100_MCLK_FREQ_100_MHZ 100000000 +#define cOCT6100_MCLK_FREQ_92_MHZ 92000000 +#define cOCT6100_MCLK_FREQ_83_MHZ 83000000 +#define cOCT6100_MCLK_FREQ_75_MHZ 75000000 + +/* Tone buffer defines.*/ +#define cOCT6100_MAX_NUM_TONE_BUFFERS 1344 +#define cOCT6100_MAX_TONES_PER_CALL 32 + +/* Memory defines.*/ +#define cOCT6100_MEM_TYPE_SDR 0 +#define cOCT6100_MEM_TYPE_DDR 1 +#define cOCT6100_MEM_TYPE_SDR_PLL_BYPASS 2 + +#define cOCT6100_MEMORY_CHIP_SIZE_8MB cOCT6100_SIZE_8M +#define cOCT6100_MEMORY_CHIP_SIZE_16MB cOCT6100_SIZE_16M +#define cOCT6100_MEMORY_CHIP_SIZE_32MB cOCT6100_SIZE_32M +#define cOCT6100_MEMORY_CHIP_SIZE_64MB cOCT6100_SIZE_64M +#define cOCT6100_MEMORY_CHIP_SIZE_128MB cOCT6100_SIZE_128M + +#define cOCT6100_MAX_NUM_MEMORY_CHIP 2 + +#define cOCT6100_16MB_MEMORY_BANKS 0 +#define cOCT6100_32MB_MEMORY_BANKS 1 +#define cOCT6100_64MB_MEMORY_BANKS 2 +#define cOCT6100_128MB_MEMORY_BANKS 3 + +#define cOCT6100_1_MEMORY_BANKS 0 +#define cOCT6100_2_MEMORY_BANKS 1 +#define cOCT6100_3_MEMORY_BANKS 2 +#define cOCT6100_4_MEMORY_BANKS 3 + +/* Chip open defines.*/ +#define cOCT6100_INTERNAL_TONE_ARRAY_SIZE 256 /* in words.*/ +#ifndef cOCT6100_INTERNAL_SUPER_ARRAY_SIZE +#define cOCT6100_INTERNAL_SUPER_ARRAY_SIZE 128 /* in words.*/ +#endif + +/* Internal memory mapping.*/ + +/*=======================================================================*/ +#define cOCT6100_TSST_CONTROL_MEM_BASE 0x26000 + +#define cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE 2 /* Each entries are 2 bytes.*/ +#define cOCT6100_TSST_CONTROL_MEM_INPUT_TSST 0x0800 +#define cOCT6100_TSST_CONTROL_MEM_OUTPUT_TSST 0x2000 + +#define cOCT6100_TSST_CONTROL_MEM_PCM_LAW_OFFSET 12 +#define cOCT6100_TSST_CONTROL_MEM_NIBBLE_POS_OFFSET 11 +#define cOCT6100_TSST_CONTROL_MEM_TSST_NUM_OFFSET 12 + +#define cOCT6100_TSST_CONTROL_MEM_TSI_MEM_MASK 0x7FF + +#define cOCT6100_TSST_CONTROL_PHASING_TSST_BASE_ENTRY 1344 +#define cOCT6100_TSST_CONTROL_TIMESTAMP_BASE_ENTRY 1516 + +/*=======================================================================*/ +#define cOCT6100_CONVERSION_CONTROL_MEM_BASE 0x28000 + +/* Each entries are 8 bytes but an 8 bytes mixer entry is located inbetween each entry.*/ +#define cOCT6100_CONVERSION_CONTROL_MEM_ENTRY_SIZE 16 +#define cOCT6100_CONVERSION_CONTROL_MEM_ENCODER 0x0000 +#define cOCT6100_CONVERSION_CONTROL_MEM_DECODER 0x8000 +#define cOCT6100_CONVERSION_CONTROL_MEM_ACTIVATE_ENTRY 0x8000 +#define cOCT6100_CONVERSION_CONTROL_MEM_RST_ON_NEXT_FR 0x8000 + +#define cOCT6100_CONVERSION_CONTROL_MEM_PHASE_OFFSET 12 +#define cOCT6100_CONVERSION_CONTROL_MEM_NIBBLE_POS_OFFSET 9 +#define cOCT6100_CONVERSION_CONTROL_MEM_COMP_OFFSET 11 +#define cOCT6100_CONVERSION_CONTROL_MEM_LAW_OFFSET 8 +#define cOCT6100_CONVERSION_CONTROL_MEM_SIL_SUP_OFFSET 8 + +#define cOCT6100_CONVERSION_CONTROL_PHASE_SIZE_BASE_ADD 0x5400 + +/*=======================================================================*/ +#define cOCT6100_MIXER_CONTROL_MEM_BASE 0x28008 + +/* Each entries are 8 bytes but an 8 bytes mixer entry is located inbetween each entry.*/ +#define cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE 16 +#define cOCT6100_MIXER_CONTROL_MEM_SUB_STORE 0xA000 +#define cOCT6100_MIXER_CONTROL_MEM_STORE 0x8000 +#define cOCT6100_MIXER_CONTROL_MEM_LOAD 0x4000 +#define cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE 0x6000 +#define cOCT6100_MIXER_CONTROL_MEM_COPY 0x2000 +#define cOCT6100_MIXER_CONTROL_MEM_NO_OP 0x0000 + +#define cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET 11 + +#define cOCT6100_MIXER_HEAD_NODE 0 +#define cOCT6100_MIXER_TAIL_NODE 1 +#define cOCT6100_MIXER_RECORD_COPY_NODE 2 + +/*=======================================================================*/ +#define cOCT6100_ECHO_CONTROL_MEM_BASE 0x14000 + +#define cOCT6100_ECHO_CONTROL_MEM_ENTRY_SIZE 4 /* Each entries are 8 bytes.*/ +#define cOCT6100_ECHO_CONTROL_MEM_ACTIVATE_ENTRY 0x8000 +#define cOCT6100_ECHO_CONTROL_MEM_EXTERNAL_AF_CTRL 0x2000 + +#define cOCT6100_ECHO_CONTROL_MEM_DEBUG_OFFSET 14 +#define cOCT6100_ECHO_CONTROL_MEM_AF_CONTROL 14 +#define cOCT6100_ECHO_CONTROL_MEM_INPUT_LAW_OFFSET 12 +#define cOCT6100_ECHO_CONTROL_MEM_OUTPUT_LAW_OFFSET 11 + +#define cOCT6100_ECHO_CONTROL_MEM_TSI_MEM_MASK 0x7FF + +/*=======================================================================*/ +#define cOCT6100_ST_CONTROL_MEM_BASE 0x2000000 + +#define cOCT6100_ST_CONTROL_MEM_ENTRY_SIZE 16 /* Each entries are 8 bytes.*/ + +/*=======================================================================*/ +#define cOCT6100_PART1_BASE 0x00080000 +#define cOCT6100_PART1_CPU_LSU_CB_BASE cOCT6100_PART1_BASE+0x0000E3C0 /* 8 * 8 = 64 bytes */ +#define cOCT6100_PART1_HW_LSU_CB_BASE cOCT6100_PART1_BASE+0x0000E400 /* 8 * 128 = 1K byte */ +#define cOCT6100_PART1_END_STATICS_BASE cOCT6100_PART1_BASE+0x0000E9F0 /* 912 bytes available for your viewing pleasure. */ +#define cOCT6100_PART1_API_SCRATCH_PAD cOCT6100_PART1_END_STATICS_BASE+4+(12*8) +#define cOCT6100_PART1_EGO_REG cOCT6100_PART1_BASE+0x0007FF00 + +/* External Memory mapping. */ +#define cOCT6100_EXTERNAL_MEM_BLOCK_SIZE 1024 +#define cOCT6100_EXTERNAL_MEM_BASE_ADDRESS 0x08000000 + + +#define cOCT6100_TLV_BASE ( 0x00016000 + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) +#define cOCT6100_CHANNEL_ROOT_BASE ( 0x00020000 + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) +#define cOCT6100_PGSP_EVENT_OUT_BASE ( 0x002C0000 + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) +#define cOCT6100_POUCH_BASE ( 0x002E0000 + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) +#define cOCT6100_IMAGE_FILE_BASE ( 0x00300000 + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) + +#define cOCT6100_CHANNEL_ROOT_SIZE 4096 +#define cOCT6100_CHANNEL_ROOT_TOTAL_SIZE ( 672 * cOCT6100_CHANNEL_ROOT_SIZE ) +#define cOCT6100_PGSP_EVENT_OUT_SIZE 131072 +#define cOCT6100_PGSP_TONE_EVENT_SIZE 0x40 +#define cOCT6100_IMAGE_FILE_SIZE 0x100000 + +#define cOCT6100_MATRIX_TIMESTAMP_DWORD_ADD cOCT6100_POUCH_BASE + 0x8 +#define cOCT6100_MATRIX_CHAN_SELECT_DWORD_ADD cOCT6100_POUCH_BASE + 0x14 +#define cOCT6100_MATRIX_WRITE_PTR_DWORD_ADD cOCT6100_POUCH_BASE + 0x4 +#define cOCT6100_MATRIX_PLL_JITTER_COUNT_ADD cOCT6100_POUCH_BASE + 0x1C +#define cOCT6100_MATRIX_DWORD_BASE cOCT6100_POUCH_BASE + 0xE0000 + +#define cOCT6100_CHANNEL_ROOT_GLOBAL_CONF_OFFSET 0x0000 + +#define cOCT6100_NUM_WORDS_PER_TONE_EVENT 32 +#define cOCT6100_NUM_PGSP_EVENT_OUT 2048 /* CPTAG: Must not be modified, represents number of events stored in hardware. */ +#define cOCT6100_VALID_TONE_EVENT 0x8000 +#define cOCT6100_LOCAL_TIMESTAMP_INCREMENT 32 /* 4 ms increment. */ +#define cOCT6100_ABSOLUTE_MAX_NUM_PGSP_EVENT_OUT 65535 +#define cOCT6100_MIN_TIMESLOT_FOR_TIMESTAMP 5 + + +/*=======================================================================*/ +#define cOCT6100_GSC_PGSP_CONTEXT_BASE_ADD_OFFSET 0x0C +#define cOCT6100_GSC_PGSP_INIT_CONTEXT_BASE_ADD_OFFSET 0x10 +#define cOCT6100_GSC_RIN_CIRC_BUFFER_BASE_ADD_OFFSET 0x14 +#define cOCT6100_GSC_SIN_CIRC_BUFFER_BASE_ADD_OFFSET 0x18 +#define cOCT6100_GSC_SOUT_CIRC_BUFFER_BASE_ADD_OFFSET 0x1C + +#define cOCT6100_GSC_BUFFER_LAW_OFFSET 27 + +/*=======================================================================*/ +#define cOCT6100_CH_MAIN_PGSP_CONTEXT_OFFSET 0x00000 +#define cOCT6100_CH_MAIN_TONE_EVENT_OFFSET 0x00488 + +/*=======================================================================*/ +#define cOCT6100_PLAYOUT_EVENT_REPEAT_OFFSET 31 +#define cOCT6100_PLAYOUT_EVENT_LAW_OFFSET 30 +#define cOCT6100_PLAYOUT_EVENT_MIX_OFFSET 28 +#define cOCT6100_PLAYOUT_EVENT_LOOP_TIMES_OFFSET 27 +#define cOCT6100_PLAYOUT_EVENT_GAIN_OFFSET 24 + +#define cOCT6100_PLAYOUT_EVENT_MEM_SIZE 16 + +/* Image related defines.*/ +#define cOCT6100_MIN_IMAGE_SIZE 0x001000 +#define cOCT6100_MAX_IMAGE_SIZE 0x100000 +#define cOCT6100_MAX_IMAGE_REGION 60 +#define cOCT6100_IMAGE_AF_CST_OFFSET 0x1000; + +/* Max defines.*/ +#ifndef cOCT6100_MAX_ECHO_CHANNELS +#define cOCT6100_MAX_ECHO_CHANNELS 128 +#endif +#define cOCT6100_MAX_TSI_CNCTS 1530 +#define cOCT6100_MAX_CALLER_ID_PLAYOUT_BUFFERS ( 3328 + 6 ) +#define cOCT6100_MAX_PLAYOUT_BUFFERS ( 1344 + cOCT6100_MAX_CALLER_ID_PLAYOUT_BUFFERS ) +#define cOCT6100_MAX_CONF_BRIDGE 672 +#define cOCT6100_MAX_FLEX_CONF_PARTICIPANTS cOCT6100_MAX_ECHO_CHANNELS +#define cOCT6100_MAX_PHASING_TSST 16 +#define cOCT6100_MAX_ADPCM_CHANNELS 672 + +#define cOCT6100_NUM_TSI_B4_PHASING 1344 +#define cOCT6100_TOTAL_TSI_CONTROL_MEM_ENTRY 1534 +#define cOCT6100_MAX_TSI_CONTROL_MEM_ENTRY 1344 +#define cOCT6100_MAX_ECHO_CONTROL_MEM_ENTRY 672 +#define cOCT6100_MAX_TSI_B4_TIMESTAMP 172 +#define cOCT6100_TSI_MEM_FOR_TIMESTAMP 4 +#define cOCT6100_API_EXT_TONE_EXTRA_TSI 1533 + +/* Echo channel ports */ +#define cOCT6100_CHANNEL_PORT_RIN 0 +#define cOCT6100_CHANNEL_PORT_ROUT 1 +#define cOCT6100_CHANNEL_PORT_SIN 2 +#define cOCT6100_CHANNEL_PORT_SOUT 3 +#define cOCT6100_CHANNEL_PORT_ROUT_SOUT 4 + +#define cOCT6100_NO_ENCODING 10 +#define cOCT6100_NO_DECODING 11 + +/* Buffer playout defines */ +#define cOCT6100_NO_SKIP 0 +#define cOCT6100_BUFFER_PLAYOUT_MIN_SIZE 1024 +#define cOCT6100_DEFAULT_TIMESTAMP 0 +#define cOCT6100_MIXING_0_DB 0 +#define cOCT6100_MIXING_MINUS_6_DB 1 +#define cOCT6100_MIXING_MINUS_12_DB 2 +#define cOCT6100_MIXING_MUTE 3 +#define cOCT6100_PLAYOUT_GAIN 0x41000000 +#define cOCT6100_PLAYOUT_EVENT 1 +#define cOCT6100_MINIMUM_BUFFER_SIZE 64 +#define cOCT6100_BUFFER_SIZE_GRANULARITY 16 +#define cOCT6100_REPEAT_INFINITELY cOCT6100_INVALID_VALUE +#define cOCT6100_REPEAT_MAX 32767 +#define cOCT6100_SAMPLES_PER_MS 8 + +/* For the playout events. */ +#define cOCT6100_MAX_BUFFER_PLAYOUT_EVENT_PER_CALL 32 +#define cOCT6100_MIN_BUFFER_PLAYOUT_EVENT 128 +#define cOCT6100_MAX_BUFFER_PLAYOUT_EVENT 65535 +/* Event types */ +#define cOCT6100_BUFFER_PLAYOUT_EVENT_INVALID cOCT6100_INVALID_VALUE +#define cOCT6100_BUFFER_PLAYOUT_EVENT_STOP 1 + + +/* Phasing defines.*/ +#define cOCT6100_SINGLE_PHASING 0 +#define cOCT6100_DUAL_PHASING 1 +#define cOCT6100_NO_PHASING 2 + +/* Echo canceller mode.*/ +#define cOCT6100_ELECTRIC_EC 0 +#define cOCT6100_ELECTRIC_EC_DISPLACEMENT 1 +#define cOCT6100_ACCOUSTIC_ES 2 + +/* Echo control modes.*/ +#define cOCT6100_ECHO_OP_MODE_NORMAL 0 +#define cOCT6100_ECHO_OP_MODE_HT_FREEZE 1 +#define cOCT6100_ECHO_OP_MODE_HT_RESET 2 +#define cOCT6100_ECHO_OP_MODE_POWER_DOWN 3 +#define cOCT6100_ECHO_OP_MODE_EXTERNAL 4 +#define cOCT6100_ECHO_OP_MODE_NO_ECHO 5 +#define cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION 6 +#define cOCT6100_ECHO_OP_MODE_G169_ALC cOCT6100_ECHO_OP_MODE_NO_ECHO + +/* 2100 Hz disabling configuration. */ +#define cOCT6100_NEVER_DISABLED 0 +#define cOCT6100_G164_2100_HZ 1 +#define cOCT6100_G165_2100_HZ_WITH_PHASE_REV 2 + +/* TSST defines.*/ +#define cOCT6100_UNASSIGNED cOCT6100_FFFD + +#define cOCT6100_MAX_TSSTS (cOCT6100_MAX_ECHO_CHANNELS*4) /* cOCT6100_MAX_ECHO_CHANNELS channels, 4 TSSTs per channel. */ +#define cOCT6100_TWO_TSSTS_INDEX_MASK 0x8000 +#define cOCT6100_TSST_INDEX_MASK 0x7FFF +#define cOCT6100_INPUT_TSST 0 +#define cOCT6100_OUTPUT_TSST 1 + +/* Conference bridges defines.*/ +/* CPTAG: No application needs for mixer events. */ +/* 2 needed for head and tail nodes. 2 more needed to get through channel modify function. */ +/* Careful. This value cannot be zero. */ +#ifndef cOCT6100_MAX_MIXER_EVENTS +#define cOCT6100_MAX_MIXER_EVENTS 4 +#endif +#define cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE 32 +#define cOCT6100_CONF_DOMINANT_SPEAKER_UNASSIGNED 672 +#define cOCT6100_CONF_NO_DOMINANT_SPEAKER_HNDL cOCT6100_FFFFFFFE + +/* Conversion memory defines.*/ +#define cOCT6100_MAX_CONVERSION_MEMORY_BLOCKS (cOCT6100_MAX_ECHO_CHANNELS*2) /* CPTAG: Max this out to the expected max number of channels * 2, was 1344 */ + +/* Tone detection defines.*/ +#define cOCT6100_MAX_TONE_NUMBER 55 + +/* Register definition and address. */ +#define cOCT6100_TONE_EVENT_WRITE_PTR_REG 0x722 +#define cOCT6100_TONE_EVENT_READ_PTR_REG 0x720 + +/* Special Signaling tone IDs. */ +#define cOCT6100_TONE_SIN_SYSTEM7_2000 0x20000023 +#define cOCT6100_TONE_SIN_SYSTEM7_1780 0x20000024 +#define cOCT6100_TONE_ROUT_G168_2100GB_ON 0x10000000 +#define cOCT6100_TONE_ROUT_G168_2100GB_WSPR 0x10000002 +#define cOCT6100_TONE_ROUT_G168_1100GB_ON 0x10000004 +#define cOCT6100_TONE_ROUT_G168_2100GB_ON_WIDE_A 0x10000005 +#define cOCT6100_TONE_ROUT_G168_2100GB_ON_WIDE_B 0x10000006 +#define cOCT6100_TONE_ROUT_G168_2100GB_WSPR_WIDE 0x10000008 +#define cOCT6100_TONE_SOUT_G168_2100GB_ON 0x40000000 +#define cOCT6100_TONE_SOUT_G168_2100GB_WSPR 0x40000002 +#define cOCT6100_TONE_SOUT_G168_1100GB_ON 0x40000004 +#define cOCT6100_TONE_SOUT_G168_2100GB_ON_WIDE_A 0x40000005 +#define cOCT6100_TONE_SOUT_G168_2100GB_ON_WIDE_B 0x40000006 +#define cOCT6100_TONE_SOUT_G168_2100GB_WSPR_WIDE 0x40000008 +#define cOCT6100_TONE_SIN_SYSTEM5_2400 0x20000020 +#define cOCT6100_TONE_SIN_SYSTEM5_2600 0x20000021 +#define cOCT6100_TONE_SIN_SYSTEM5_2400_2600 0x20000022 + +#define cOCT6100_CHIP_ID_REVISION_REG 0x17E + +/* BOOT type. */ +#define cOCT6100_AF_BOOT_TYPE 0x5 +#define cOCT6100_PRODUCTION_BOOT_TYPE 0x7 +#define cOCT6100_PRODUCTION_SHORT_BOOT_TYPE 0x8 + +/*Production Bist Modes*/ +#define cOCT6100_PRODUCTION_BIST_STANDARD 0x0 +#define cOCT6100_PRODUCTION_BIST_SHORT 0x1 + +/* Interrupt register masks.*/ +#define cOCT6100_INTRPT_MASK_REG_102H 0x0001 +#define cOCT6100_INTRPT_MASK_REG_202H 0x1C01 +#define cOCT6100_INTRPT_MASK_REG_302H 0xF100 +#define cOCT6100_INTRPT_MASK_REG_502H 0x0002 +#define cOCT6100_INTRPT_MASK_REG_702H 0x0002 + +#define cOCT6100_DECODER_MEMORY_OFFSET 672 + +/* Debug defines.*/ +#define cOCT6100_DEBUG_MAX_READ_LENGTH 10240 +#define cOCT6100_DEBUG_SOUT_MAX_READ_LENGTH 2560 +#define cOCT6100_DEBUG_CHAN_RECORD_INDEX 64 +#define cOCT6100_DEBUG_RECORD_BUFFER_BYTE_SIZE 0x20000 +#define cOCT6100_DEBUG_RECORD_MATRIX_SIZE 0x8000 +#define cOCT6100_DEBUG_RECORD_READ_DATA_BYTE_SIZE 1024 +#define cOCT6100_DEBUG_RECORD_BLOCK_BYTE_SIZE 0x1000 + +/* Tone event defines.*/ +#define cOCT6100_MAX_TONE_EVENT 56 +#define cOCT6100_TONE_PRESENT 0 +#define cOCT6100_TONE_STOP 1 +#define cOCT6100_TONE_REFRESH 2 + +/* TLV defines.*/ +#define cOCT6100_TLV_MAX_ADDRESS 0x10000000 +#define cOCT6100_TLV_MAX_TONE_NAME_SIZE 64 + +#define cOCT6100_VERSION_NUMBER_MAX_SIZE 1016 + +/* Echo Tail defines.*/ +#define cOCT6100_TAIL_LENGTH_32MS 32 +#define cOCT6100_TAIL_LENGTH_64MS 64 +#define cOCT6100_TAIL_LENGTH_128MS 128 +#define cOCT6100_MAX_ECHO_TAIL_DISPLACEMENT 5600 /* In milliseconds */ + + + + + +/* Generic loop counter.*/ +#define cOCT6100_MAX_LOOP 0x2000 +/* CPU boot timeout counter. */ +#define cOCT6100_MAX_LOOP_CPU_TIMEOUT 0x20000 + +/* Automatic level control */ +#define cOCT6100_PASS_THROUGH_LEVEL_CONTROL 0x90 + +/* Channel stats debug info */ +#define cOCT6100_DEBUG_CHAN_STATS_EVENT_BYTE_SIZE 1024 +#define cOCT6100_DEBUG_CHAN_STATS_LITE_EVENT_BYTE_SIZE 720 + +/* Image start string define */ +#define cOCT6100_IMAGE_START_STRING "EDS3_IMAGE_NAME" + +/* Tone image info defines.*/ +#define cOCT6100_TONE_INFO_START_STRING "[ToneDetectorInfo]" +#define cOCT6100_TONE_INFO_STOP_STRING "[~ToneDetectorInfo]" +#define cOCT6100_TONE_INFO_EVENT_STRING "TONEEVENT=0x" + +#define cOCT6100_MAX_NLP_CONF_DWORD 20 + +/* Tail displacement info.*/ +#define cOCT6100_MAX_TAIL_DISPLACEMENT 896 + +/* Comfort noise define */ +#define cOCT6100_COMFORT_NOISE_NORMAL 0x0 +#define cOCT6100_COMFORT_NOISE_EXTENDED 0x3 +#define cOCT6100_COMFORT_NOISE_OFF 0x2 +#define cOCT6100_COMFORT_NOISE_FAST_LATCH 0x1 + +/* Mixer event type.*/ +#define cOCT6100_EVENT_TYPE_SOUT_COPY 0x0 +#define cOCT6100_EVENT_TYPE_SIN_COPY 0x1 + +/* Tone disabler status.*/ +#define cOCT6100_TONE_DISABLER_EC_ENABLED 0 +#define cOCT6100_TONE_DISABLER_EC_DISABLED 1 + +/* ADPCM Channel defines */ +#define cOCT6100_ADPCM_ENCODING 0 +#define cOCT6100_ADPCM_DECODING 1 + +/* Double talk behavior modes. */ +#define cOCT6100_DOUBLE_TALK_BEH_NORMAL 0x0 +#define cOCT6100_DOUBLE_TALK_BEH_LESS_AGGRESSIVE 0x1 + +/* Api Version string length.*/ +#define cOCT6100_API_VERSION_STRING_LENGTH 32 + +/* Extended tone detection information. */ +#define cOCT6100_API_EXT_TONE_DISABLED 0 +#define cOCT6100_API_EXT_TONE_SIN_PORT_MODE 1 +#define cOCT6100_API_EXT_TONE_RIN_PORT_MODE 2 + + + +/* Mute/UnMute defines. */ +#define cOCT6100_CHANNEL_MUTE_PORT_NONE 0x00 +#define cOCT6100_CHANNEL_MUTE_PORT_RIN 0x01 +#define cOCT6100_CHANNEL_MUTE_PORT_ROUT 0x02 +#define cOCT6100_CHANNEL_MUTE_PORT_SIN 0x04 +#define cOCT6100_CHANNEL_MUTE_PORT_SOUT 0x08 +#define cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES 0x10 + +/* Debug get data dump modes. */ +#define cOCT6100_DEBUG_GET_DATA_MODE_16S_LITE 0x0 +#define cOCT6100_DEBUG_GET_DATA_MODE_120S_LITE 0x1 +#define cOCT6100_DEBUG_GET_DATA_MODE_16S 0x2 +#define cOCT6100_DEBUG_GET_DATA_MODE_120S 0x3 + +/* Debug get data dump content. */ +#define cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE 0x0 /* Full binary dump to be sent for support. */ +#define cOCT6100_DEBUG_GET_DATA_CONTENT_RIN_PCM 0x1 /* Only Rin PCM stream data. */ +#define cOCT6100_DEBUG_GET_DATA_CONTENT_SIN_PCM 0x2 /* Only Sin PCM stream data. */ +#define cOCT6100_DEBUG_GET_DATA_CONTENT_SOUT_PCM 0x3 /* Only Sout PCM stream data. */ + + + +#define cOCT6100_BIST_IN_PROGRESS 0x0 +#define cOCT6100_BIST_CONFIGURATION_FAILED 0x1 +#define cOCT6100_BIST_STATUS_CRC_FAILED 0x2 +#define cOCT6100_BIST_MEMORY_FAILED 0x3 +#define cOCT6100_BIST_SUCCESS 0x4 + +/* Image types. */ +#define cOCT6100_IMAGE_TYPE_WIRELINE 0x0 +#define cOCT6100_IMAGE_TYPE_COMBINED 0x1 + +/* Fatal general error types. */ +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_1 0x0001 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_2 0x0002 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_3 0x0004 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_4 0x0008 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_5 0x0010 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_6 0x0020 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_7 0x0040 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_8 0x0080 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_9 0x0100 + +#endif /* __OCT6100_DEFINES_H__ */ + diff --git a/xpp/oct612x/include/oct6100api/oct6100_errors.h b/xpp/oct612x/include/oct6100api/oct6100_errors.h new file mode 100644 index 0000000..a123762 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_errors.h @@ -0,0 +1,838 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_errors.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Header file containing all defines used for error codes. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 205 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_ERRORS_H__ +#define __OCT6100_ERRORS_H__ + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +/***************************** DEFINES *************************************/ + +#define cOCT6100_ERR_OK 0x00000000 +#define cOCT6100_ERR_BASE 0x00100000 + +#define cOCT6100_NOT_SUPPORTED_BASE (0xFF000 + cOCT6100_ERR_BASE) + +/* Not supported defines. */ +#define cOCT6100_ERR_NOT_SUPPORTED_OPEN_DEBUG_RECORD (0x00000 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NLP_CONTROL (0x00001 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_BKG_NOISE_FREEZE (0x00002 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SIN_DC_OFFSET_REM (0x00003 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_RIN_DC_OFFSET_REM (0x00004 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_RIN_AUTO_LC (0x00005 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SOUT_AUTO_LC (0x00006 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ANR (0x00007 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TAIL_DISPLACEMENT (0x00008 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ENCODING (0x00009 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_DECODING (0x0000A + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_LAW_TRANSLATION (0x0000B + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ACOUSTIC_ECHO (0x0000C + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_DEFAULT_ERL (0x0000D + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_DOUBLE_TALK (0x0000E + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NON_LINEARITY_B (0x0000F + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_AEC_DEFAULT_ERL (0x00010 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_RIN_HIGH_LEVEL_COMP (0x00011 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_PER_CHAN_TAIL (0x00012 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SIL_SUP (0x00013 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_OPEN_ACOUSTIC_ECHO (0x00014 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_OPEN_TAIL_DISPLACEMENT_VALUE (0x00015 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_OPEN_MAX_ECHO_CHANNELS_VALUE (0x00016 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ALE (0x00017 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NLE (0x00018 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ROUT_NR (0x00019 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SIN_MUTE_FEATURES (0x0001A + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ANR_SNR_ENHANCEMENT (0x0001B + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ANR_SEGREGATION (0x0001C + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_OPEN_USE_SYNCH_TIMESTAMP (0x0001D + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TAIL_LENGTH (0x0001E + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TONE_DISABLER_ACTIVATION_DELAY (0x0001F + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ACOUSTIC_ECHO_TAIL_LENGTH (0x00020 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_MUSIC_PROTECTION (0x00021 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_DEBUG_DATA_MODE_120S (0x00022 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_TONE_NOT_PRESENT_IN_FIRMWARE (0x00023 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_DOUBLE_TALK_BEHAVIOR_MODE (0x00024 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_IDLE_CODE_DETECTION (0x00025 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_IDLE_CODE_DETECTION_CONFIG (0x00026 + cOCT6100_NOT_SUPPORTED_BASE) + + +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ROUT_NOISE_REDUCTION_GAIN (0x0002B + cOCT6100_NOT_SUPPORTED_BASE) + +#define cOCT6100_ERR_NOT_SUPPORTED_BUFFER_PLAYOUT (0x00100 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_CNR (0x00101 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CONF_BRIDGE (0x00102 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CALLER_ID (0x00104 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NOISE_BLEACHING (0x00105 + cOCT6100_NOT_SUPPORTED_BASE) + +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TONE_REMOVAL (0x00300 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_DOMINANT_SPEAKER (0x00301 + cOCT6100_NOT_SUPPORTED_BASE) + + + +#define cOCT6100_ERR_OPEN_INVALID_DEVICE (0x03000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INSUFFICIENT_EXTERNAL_MEMORY (0x03001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MEMORY_CHIP_SIZE (0x03002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_UP_CLK_FREQ (0x03003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_USER_CHIP_ID (0x03004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MULTI_PROCESS_SYSTEM (0x03005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_RW_ACCESSES (0x03006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_IMAGE_SIZE (0x03007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_IMAGE_FILE (0x03008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MEM_CLK_FREQ (0x03009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MEMORY_CHIPS_NUMBER (0x0300A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TOTAL_MEMORY_SIZE (0x0300B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_USE_SYNCH_TIMESTAMP (0x0300C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TIMESTAMP_STREAM (0x0300D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TIMESTAMP_TIMESLOT (0x0300E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TIMESTAMP_TSSTS (0x0300F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TDM_STREAM_FREQS (0x03010 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TDM_SAMPLING (0x03011 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_FAST_H100_MODE (0x03012 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_ECHO_CHANNELS (0x03013 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_PLAYOUT_BUFFERS (0x03014 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_TSI_CNCTS (0x03015 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_PHASING_TSSTS (0x03016 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_EXTERNAL_MEM_BIST_FAILED (0x03017 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_EXTERNAL_MEM_BIST_TIMEOUT (0x03018 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_SDRAM_BIST_FAILED (0x03019 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_CORRUPTED_IMAGE (0x0301A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR (0x0301B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_SOFT_TONE_EVENT_SIZE (0x0301C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INTERRUPT_POLARITY (0x0301D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_FATAL_GENERAL_CONFIG (0x0301E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_REMOTE_DEBUG_SESSIONS (0x0301F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ENABLE_MEM_CLK_OUT (0x03020 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_TDM_STREAM (0x03021 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_CONF_BRIDGES (0x03022 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_OPEN_AF_CPU_TIMEOUT (0x03024 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MEMORY_TYPE (0x03025 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_FATAL_MEMORY_CONFIG (0x03026 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ERROR_MEMORY_CONFIG (0x03027 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ERROR_OVERFLOW_TONE_EVENTS_CONFIG (0x03028 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ERROR_H100_CONFIG (0x03029 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_FATAL_MEMORY_TIMEOUT (0x0302A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ERROR_MEMORY_TIMEOUT (0x0302B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ERROR_OVERFLOW_TONE_EVENTS_TIMEOUT (0x0302C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ERROR_H100_TIMEOUT (0x0302D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_IMAGE_WRITE_FAILED (0x0302E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_CRC_ERROR (0x0302F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_EGO_TIMEOUT (0x03030 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_SOFT_DEBUG_EVENT_BUF_SIZE (0x03031 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TONE_INFO_START_TAG_NOT_FOUND (0x03032 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TONE_INFO_STOP_TAG_NOT_FOUND (0x03033 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INVALID_TONE_EVENT (0x03034 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INVALID_TONE_NAME (0x03035 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INVALID_EVENT_NUMBER_SIZE (0x03036 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INTERNAL_MEMORY_BIST (0x03037 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TAIL_DISPLACEMENT (0x03038 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_DEBUG_CHANNEL_RECORDING (0x03039 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_BIDIR_CHANNELS (0x0303A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_FUNCTIONAL_BIST_FAILED (0x0303C + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_OPEN_MAX_ADPCM_CHANNELS (0x0303E + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_OPEN_ENABLE_EXT_TONE_DETECTION (0x03040 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_SOFT_PLAYOUT_STOP_EVENT_SIZE (0x03041 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INVALID_FIRMWARE_OR_CAPACITY_PINS (0x03042 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ENABLE_ACOUSTIC_ECHO (0x03043 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_OPEN_USER_WRITE_BURST_FAILED (0x03045 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_USER_WRITE_SMEAR_FAILED (0x03046 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_USER_READ_BURST_FAILED (0x03047 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_FLEXIBLE_CONF_PARTICIPANTS (0x03048 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_OPEN_DEBUG_MEM_INDEX (0x03051 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ENABLE_CALLER_ID (0x03052 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_CALLER_ID_PLAYOUT_BUFFERS (0x03053 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_OPEN_ENABLE_PRODUCTION_BIST (0x03055 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_PRODUCTION_BIST_ACTIVATED (0x03056 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_NUM_PRODUCTION_BIST_LOOPS (0x03057 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_PRODUCTION_BOOT_FAILED (0x03058 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_PRODUCTION_BIST_CONF_FAILED (0x03059 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_PRODUCTION_BIST_POUCH_ERROR (0x0305A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INVALID_TLV_LENGTH (0x0305B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_PRODUCTION_BIST_MODE (0x0305C + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_OPEN_ENABLE_2100_STOP_EVENT (0x03060 + cOCT6100_ERR_BASE) + + +#define cOCT6100_ERR_CAP_PINS_INVALID_CHIP_STATE (0x03081 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CAP_PINS_INVALID_CAPACITY_VALUE (0x03082 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_TSI_CNCT_ALL_CHANNELS_ARE_OPENED (0x04000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_DISABLED (0x04001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_INVALID_HANDLE (0x04002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_INPUT_TIMESLOT (0x04003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_INPUT_STREAM (0x04004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_OUTPUT_TIMESLOT (0x04005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_OUTPUT_STREAM (0x04006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_INPUT_PCM_LAW (0x04007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_TIMESLOT (0x04008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_STREAM (0x04009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_TSST_RESERVED (0x0400A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_NOT_OPEN (0x0400B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_ASSOCIATED_TSST_RESERVED (0x0400C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_NO_MORE_TSI_AVAILABLE (0x0400D + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_BUFFER_PLAYOUT_DISABLED (0x05000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_PATTERN (0x05001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_TOO_SMALL (0x05002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_PCM_LAW (0x05003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ALL_BUFFERS_OPEN (0x05004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_BUF_SIZE (0x05005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_BUF_INDEX (0x05006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_NOT_OPEN (0x05007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ACTIVE_DEPENDENCIES (0x05008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID (0x05009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_NOT_OPEN (0x0500A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ROUT_PORT_PLAYING (0x0500B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_SOUT_PORT_PLAYING (0x0500C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_PORT_INVALID (0x0500D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_PLAYOUT_PORT (0x0500E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ADD_EVENT_BUF_FULL (0x0500F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ADD_REPEAT (0x05010 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ADD_MIXING (0x05011 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_STOP_CLEANLY (0x05012 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_NOT_STARTED (0x05013 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_WRITE_BYTE_COUNT (0x05015 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ECHO_OP_MODE (0x05016 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_BLOCK_LENGTH_INVALID (0x05017 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_BLOCK_OFFSET_INVALID (0x05018 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_RESET (0x05019 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_BUF_EMPTY (0x0501A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_MAX_EVENT (0x0501B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_DISABLED (0x0501C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_NOTIFY_ON_STOP (0x0501D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ALLOW_ACTIVE (0x0501E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_STILL_ACTIVE (0x0501F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_REPEAT_USED (0x05020 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_NLP_DISABLED (0x05021 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_MALLOC_ZERO (0x05022 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_NO_MEMORY (0x05023 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_MALLOC_POINT_NOT_FOUND (0x05024 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ADD_REPEAT_COUNT (0x05025 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ADD_GAIN_DB (0x05026 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_LIST_EMPTY (0x05027 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_MEMORY_ALL_TSI_MEM_ENTRY_RESERVED (0x06000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MEMORY_ALL_ECHO_MEM_ENTRY_RESERVED (0x06002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MEMORY_EXTERNAL_MEMORY_FULL (0x06003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MEMORY_ALL_CONVERSION_MEM_ENTRY_RESERVED (0x06004 + cOCT6100_ERR_BASE) + + +#define cOCT6100_ERR_CHANNEL_DISABLED (0x07000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_INVALID_HANDLE (0x07001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_NUM_TSSTS (0x07002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_NUM_TSSTS (0x07003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_NUM_TSSTS (0x07004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_NUM_TSSTS (0x07005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_TIMESLOT (0x07006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_STREAM (0x07007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_TIMESLOT (0x07008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_STREAM (0x07009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_TIMESLOT (0x0700A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_STREAM (0x0700B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_TIMESLOT (0x0700C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_STREAM (0x0700D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_MISSING_TSST (0x07012 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIL_SUP_ENABLE (0x07013 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_PHASING_TYPE (0x07014 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_INVALID_PHASING_HANDLE (0x07015 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_PHASING_TSST_NOT_OPEN (0x07016 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_PHASING_INVALID_PHASE (0x07017 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_DEBUG (0x07018 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ECHO_OP_MODE (0x0701F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_DC_OFFSET_REM (0x07020 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_DC_OFFSET_REM (0x07021 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_LEVEL_CONTROL (0x07022 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_LEVEL_CONTROL (0x07023 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_LEVEL_CONTROL_GAIN (0x07024 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_LEVEL_CONTROL_GAIN (0x07025 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_ADAPT_NOISE_REDUCTION (0x07026 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ALL_CHANNELS_ARE_OPENED (0x07027 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_NOT_OPEN (0x07029 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ADPCM_NIBBLE (0x0702A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_ADD_PORT (0x0702B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_ADD_TIMESLOT (0x0702C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_ADD_STREAM (0x0702D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_INVALID (0x0702E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_PCM_LAW (0x0702F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_PCM_LAW (0x07030 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_PCM_LAW (0x07031 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_PCM_LAW (0x07032 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_DECODER_PORT (0x07033 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ENCODER_PORT (0x07034 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_DECODING_RATE (0x07035 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ENCODING_RATE (0x07036 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ENABLE_NLP (0x07037 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_COMFORT_NOISE_MODE (0x07038 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_PHASING_TSST_REQUIRED (0x07039 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIL_SUP_INVALID_ENCODER_PORT (0x0703A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_MODIFY_CODEC_CONFIG (0x0703B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_MODIFY_VQE_CONFIG (0x0703C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_MODIFY_TDM_CONFIG (0x0703D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_RIN_PORT_INVALID (0x0703E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_SIN_PORT_INVALID (0x0703F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_REMOVE_PORT (0x07041 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_REMOVE_TIMESLOT (0x07042 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_REMOVE_STREAM (0x07043 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_REMOVE_INVALID_TSST (0x07044 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_GET_STATS_MAX_BROADCAST_TSST (0x07045 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_BROADCAST_TIMESLOT (0x07046 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_BROADCAST_STREAM (0x07047 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_BROADCAST_TIMESLOT (0x07048 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_BROADCAST_STREAM (0x07049 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ACTIVE_DEPENDENCIES (0x0704A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TONE_DISABLER_ENABLE (0x0704B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TAIL_LENGTH (0x07053 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TAIL_DISPLACEMENT (0x07054 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_INVALID_RIN_CB_SIZE (0x07058 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_REMOVE_NO_BROADCAST_TSST (0x07059 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_INVALID_CODEC_POSITION (0x0705A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_STATS_RESET (0x0705B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ENABLE_TAIL_DISPLACEMENT (0x0705C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_BIDIR_CHANNEL_HANDLE (0x0705E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_BIDIR_FIRST_CHANNEL_HANDLE (0x0705F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_BIDIR_SECOND_CHANNEL_HANDLE (0x07060 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_CODEC_ACTIVATED (0x07061 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ALREADY_BIDIR (0x07062 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ALL_BIDIR_CHANNELS_ARE_OPENED (0x07063 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_FIRST_CHAN_SOUT_PORT (0x07064 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_FIRST_CHAN_RIN_PORT (0x07065 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SECOND_CHAN_SOUT_PORT (0x07066 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SECOND_CHAN_RIN_PORT (0x07067 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_BIDIR_PCM_LAW (0x07068 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_BIDIR_CHAN_NOT_OPEN (0x07069 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_ROUT_LAW_CONVERSION (0x0706A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_SOUT_LAW_CONVERSION (0x0706B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_PART_OF_BIDIR_CHANNEL (0x0706C + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_NO_VALID_TDM_CLOCKS (0x0706E + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_OUT_OF_TSI_MEMORY (0x07073 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TONE_REMOVAL (0x07075 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ACOUSTIC_ECHO (0x07077 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_DEFAULT_ERL (0x07079 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_DOUBLE_TALK (0x0707B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_PHASE_TYPE_REQUIRED (0x0707C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIL_SUP_NLP_MUST_BE_ENABLED (0x0707D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ENABLE_EXT_TONE_DETECTION (0x0707E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_EXT_TONE_DETECTION_DECODER_PORT (0x0707F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_EXT_TONE_DETECTION_DISABLED (0x07080 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_NON_LINEARITY_B (0x07082 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_FIRST_CHAN_IN_CONFERENCE (0x07083 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SECOND_CHAN_IN_CONFERENCE (0x07084 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TAIL_DISPLACEMENT_CANNOT_MODIFY (0x07085 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_NON_LINEARITY_B_CANNOT_MODIFY (0x07086 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ACOUSTIC_ECHO_NOT_ENABLED (0x07087 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_BIDIR_DISABLED (0x0708B + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_TAIL_DISPLACEMENT_INVALID (0x0708D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_PER_CHAN_TAIL_DISPLACEMENT (0x0708E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_CONFERENCE_NOISE_REDUCTION (0x0708F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_AEC_DEFAULT_ERL (0x07092 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_NLP_REQUIRED (0x07093 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_CONTROL (0x07094 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_AUTO_LEVEL_CONTROL (0x07095 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_CONTROL_TARGET (0x07096 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_AUTO_LEVEL_CONTROL_TARGET (0x07097 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_MANUAL (0x07098 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_AUTO_LEVEL_MANUAL (0x07099 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_HIGH_LEVEL_COMP (0x0709A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_HIGH_LEVEL_COMP (0x0709C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_HIGH_LEVEL_COMP_MANUAL (0x0709D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_HIGH_LEVEL_COMP_THRESHOLD (0x0709E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_MUTE_MASK (0x0709F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_MUTE_MASK_SIN (0x070A0 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ALE_RATIO (0x070A1 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_NLE_FLAG (0x070A2 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ALE_NLE_SIMULTANEOUSLY (0x070A3 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_NOISE_REDUCTION (0x070A4 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ANR_SNR_ENHANCEMENT (0x070A5 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ANR_SEGREGATION (0x070A6 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_NLE_RATIO (0x070A7 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_APPLY_TO_ALL_CHANNELS (0x070A8 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_STREAM_UNASSIGN (0x070A9 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_TIMESLOT_UNASSIGN (0x070AA + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_STREAM_UNASSIGN (0x070AB + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_TIMESLOT_UNASSIGN (0x070AC + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_STREAM_UNASSIGN (0x070AD + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_TIMESLOT_UNASSIGN (0x070AE + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_STREAM_UNASSIGN (0x070AF + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_TIMESLOT_UNASSIGN (0x070B0 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_DISABLE_TONE_DETECTION (0x070B1 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_STOP_BUFFER_PLAYOUT (0x070B2 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_REMOVE_CONF_BRIDGE_PARTICIPANT (0x070B3 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_REMOVE_BROADCAST_TSSTS (0x070B4 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TONE_DISABLER_ACTIVATION_DELAY (0x070B5 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_OUT_OF_MIXER_EVENTS (0x070B8 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ACOUSTIC_ECHO_TAIL_LENGTH (0x070B9 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ENABLE_MUSIC_PROTECTION (0x070BA + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TAIL_LENGTH_INVALID (0x070BB + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ACOUSTIC_ECHO_TAIL_SUM (0x070BC + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_DOUBLE_TALK_MODE (0x070BD + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_NOISE_BLEACHING (0x070BE + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_NOISE_BLEACHING_NR (0x070BF + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ANR_CNR_SIMULTANEOUSLY (0x070C0 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_IDLE_CODE_DETECTION (0x070C1 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_MUST_ENABLE_TONE_DISABLER (0x070C2 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_CONTROL_REQUIRED (0x070C5 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_AUTO_LEVEL_CONTROL_REQUIRED (0x070C6 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_AUTO_LEVEL_CONTROL_REQUIRED (0x070C8 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_COMFORT_NOISE_REQUIRED (0x070CB + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_NOISE_REDUCTION_GAIN (0x070CC + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_PHASING_TSST_ALL_ENTRIES_ARE_OPENED (0x08000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_PHASING_TSST_DISABLED (0x08001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_PHASING_TSST_INVALID_HANDLE (0x08002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_PHASING_TSST_TIMESLOT (0x08003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_PHASING_TSST_STREAM (0x08004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_PHASING_TSST_PHASING_LENGTH (0x08005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_PHASING_TSST_NOT_OPEN (0x08006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_PHASING_TSST_ACTIVE_DEPENDENCIES (0x08007 + cOCT6100_ERR_BASE) + + +#define cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE (0x09000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_DISABLED (0x09001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN (0x09002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_ACTIVE_DEPENDENCIES (0x09003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_HANDLE (0x09004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_MIXER_EVENT_NOT_FOUND (0x09005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_ALL_BUFFERS_OPEN (0x09006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_REMOVE_INVALID_HANDLE (0x09007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHAN_NOT_ON_BRIDGE (0x09008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_MUTE (0x09009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_INVALID_HANDLE (0x0900A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_ALREADY_MUTED (0x0900B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_NOT_MUTED (0x0900C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_CODEC_ACTIVE (0x0900D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_MIXER_FULL (0x0900E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ALREADY_ON_BRIDGE (0x0900F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_REMOVE_ALL (0x09010 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_EXT_TONE_ENABLED (0x09011 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_INVALID_INPUT_PORT (0x09012 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_DOMINANT_SPEAKER (0x09013 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_BIDIR (0x09015 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CNR_MUST_BE_ENABLED (0x09016 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_NLP_MUST_BE_ENABLED (0x09017 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF (0x09018 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_PARTICIPANT_CNT (0x09019 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_LISTENER_MASK_INDEX (0x0901A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_ALL_BUFFERS_OPEN (0x0901B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_DISABLED (0x0901C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_LISTENER_INDEX_USED (0x0901D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_SIMPLE_BRIDGE (0x0901E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_COPY_EVENTS (0x0901F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_TAP_HANDLE (0x09020 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_TAP_NOT_SUPPORTED (0x09021 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_NOT_ON_BRIDGE (0x09022 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_DEPENDENCY (0x09023 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_NOT_ON_SAME_BRIDGE (0x09024 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_TAP_SOUT_ONLY (0x09025 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_ALREADY_TAPPED (0x09026 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_ALWAYS_MUTE (0x09027 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_LAW_CONVERSION (0x09028 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_MISC_CANNOT_ROUND_UP_NUMBER (0x0A000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MISC_ASCII_CONVERSION_FAILED (0x0A001 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_TONE_DETECTION_CHANNEL_HANDLE_INVALID (0x0B000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TONE_DETECTION_CHANNEL_NOT_OPEN (0x0B001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TONE_DETECTION_TONE_NUMBER_INVALID (0x0B002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TONE_DETECTION_TONE_NOT_ACTIVATED (0x0B003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TONE_DETECTION_TONE_ACTIVATED (0x0B004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TONE_DETECTION_TONE_NOT_AVAILABLE (0x0B005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TONE_DETECTION_DISABLE_ALL (0x0B006 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_EVENTS_GET_TONE_RESET_BUFS (0x0C000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_EVENTS_TONE_BUF_EMPTY (0x0C001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_EVENTS_MAX_TONES (0x0C002 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_INTRPTS_RW_ERROR (0x0D000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_NOT_ACTIVE (0x0D001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_FATAL_GENERAL_CONFIG (0x0D002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_FATAL_MEMORY_CONFIG (0x0D003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_DATA_ERR_MEMORY_CONFIG (0x0D004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_OVERFLOW_TONE_EVENTS_CONFIG (0x0D005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_H100_ERROR_CONFIG (0x0D006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_FATAL_GENERAL_TIMEOUT (0x0D007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_FATAL_MEMORY_TIMEOUT (0x0D008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_DATA_ERR_MEMORY_TIMEOUT (0x0D009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_OVERFLOW_TONE_EVENTS_TIMEOUT (0x0D00A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_H100_ERROR_TIMEOUT (0x0D00B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_AF_TIMESTAMP_READ_TIMEOUT (0x0D00C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_NLP_TIMESTAMP_READ_TIMEOUT (0x0D00D + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_TSST_TIMESLOT (0x0E000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSST_STREAM (0x0E001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSST_TSST_RESERVED (0x0E002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSST_ASSOCIATED_TSST_RESERVED (0x0E003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSST_ALL_TSSTS_ARE_OPENED (0x0E004 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_MULTIPROC_API_INST_SHARED (0x10000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MULTIPROC_API_INST_LOCAL (0x10001 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_DEBUG_CHANNEL_INVALID_HANDLE (0x11000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_PORT (0x11001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_READ_LENGTH (0x11002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_SOUT_READ_LENGTH (0x11003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_READ_DATA (0x11004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_GET_EVENTS_RESET_BUFS (0x11005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_GET_EVENTS_BUF_EMPTY (0x11006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RECORD_RIN_PTR_INVALID (0x11007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RECORD_SIN_PTR_INVALID (0x11008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RECORD_ROUT_PTR_INVALID (0x11009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RECORD_SOUT_PTR_INVALID (0x1100A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RECORD_RAW_DATA_PTR_INVALID (0x1100B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RECORD_LENGTH_INVALID (0x1100C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RECORD_NO_CHAN_SELECTED (0x1100D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_PCM_LAW (0x1100E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_CHANNEL_RECORDING_DISABLED (0x1100F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_GET_DATA_MAX_BYTES (0x11010 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_GET_DATA_PTR_INVALID (0x11011 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RC_CHANNEL_RECORDING_DISABLED (0x11012 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_GET_DATA_MODE (0x11013 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_CHANNEL_IN_POWER_DOWN (0x11014 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_GET_DATA_CONTENT (0x11015 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_GET_DATA_MODE_CANNOT_CHANGE (0x11016 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_MIXER_ALL_COPY_EVENT_ENTRY_OPENED (0x12000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_COPY_EVENT_HANDLE (0x12001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_SOURCE_CHAN_HANDLE (0x12002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_DESTINATION_CHAN_HANDLE (0x12003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_SOURCE_PORT (0x12004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_DESTINATION_PORT (0x12005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_EVENT_NOT_OPEN (0x12006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_SOURCE_ADPCM_RESOURCES_ACTIVATED (0x12007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_DEST_ADPCM_RESOURCES_ACTIVATED (0x12008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_ALL_MIXER_EVENT_ENTRY_OPENED (0x12009 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_ADPCM_CHAN_DISABLED (0x13000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_INVALID_HANDLE (0x13001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_INPUT_TIMESLOT (0x13002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_INPUT_STREAM (0x13003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_OUTPUT_TIMESLOT (0x13004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_OUTPUT_STREAM (0x13005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_INPUT_NUM_TSSTS (0x13006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_OUTPUT_NUM_TSSTS (0x13007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_INPUT_PCM_LAW (0x13008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_MODE (0x13009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_ENCODING_RATE (0x1300A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_DECODING_RATE (0x1300B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_INCOMPATIBLE_NUM_TSSTS (0x1300C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_NO_MORE_TSI_AVAILABLE (0x1300D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_OUTPUT_PCM_LAW (0x1300E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_ADPCM_NIBBLE_POSITION (0x1300F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_NOT_OPEN (0x13010 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_ALL_ADPCM_CHAN_ARE_OPENED (0x13011 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHIP_STATS_RESET (0x14000 + cOCT6100_ERR_BASE) + + + +#define cOCT6100_ERR_PRODUCTION_BIST_DISABLED (0x16000 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_REMOTEDEBUG_RECEIVED_PKT_PAYLOAD (0x2C000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_RESPONSE_PKT_PAYLOAD (0x2C001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_RECEIVED_PKT_LENGTH (0x2C002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_RESPONSE_PKT_LENGTH (0x2C003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_ENDIAN_DETECTION_FIELD (0x2C004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_CHECKSUM (0x2C005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTE_DEBUG_PARSING_ERROR (0x2C006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_ALL_SESSIONS_OPEN (0x2C007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_INVALID_PACKET (0x2C008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_TRANSACTION_ANSWERED (0x2C009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_INAVLID_SESSION_NUMBER (0x2C00A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_INVALID_HOT_CHAN_INDEX (0x2C00B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_DISABLED (0x2C00C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_INVALID_RPC_COMMAND_NUM (0x2C00D + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_TLV_TIMEOUT (0x31000 + cOCT6100_ERR_BASE) + +/* Fatal errors must always be greater or equal to 0xE000. */ +#define cOCT6100_ERR_FATAL (0xDE000 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_FATAL_DRIVER_WRITE_API (0xDE000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_FATAL_DRIVER_WRITE_EXT_API (0xDE001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_FATAL_DRIVER_WRITE_SMEAR_API (0xDE002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_FATAL_DRIVER_WRITE_BURST_API (0xDE003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_FATAL_DRIVER_READ_API (0xDE004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_FATAL_DRIVER_READ_BURST_API (0xDE005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_FATAL_DRIVER_READ_DEBUG_API (0xDE006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_FATAL_DRIVER_WRITE_ARRAY_API (0xDE007 + cOCT6100_ERR_BASE) + +#define cOCT6100_FATAL_BASE (0xDF000 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_FATAL_0 (0x00000 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_1 (0x00001 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_2 (0x00002 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_3 (0x00003 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_4 (0x00004 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_5 (0x00005 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_6 (0x00006 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_7 (0x00007 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_8 (0x00008 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_9 (0x00009 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A (0x0000A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B (0x0000B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C (0x0000C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D (0x0000D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E (0x0000E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_F (0x0000F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_10 (0x00010 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_11 (0x00011 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_12 (0x00012 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_13 (0x00013 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_14 (0x00014 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_15 (0x00015 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_16 (0x00016 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_17 (0x00017 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_18 (0x00018 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_19 (0x00019 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_1A (0x0001A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_1B (0x0001B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_1C (0x0001C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_1D (0x0001D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_1E (0x0001E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_1F (0x0001F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_20 (0x00020 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_21 (0x00021 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_22 (0x00022 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_23 (0x00023 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_24 (0x00024 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_25 (0x00025 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_26 (0x00026 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_27 (0x00027 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_28 (0x00028 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_29 (0x00029 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_2A (0x0002A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_2B (0x0002B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_2C (0x0002C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_2D (0x0002D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_2E (0x0002E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_2F (0x0002F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_30 (0x00030 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_31 (0x00031 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_32 (0x00032 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_33 (0x00033 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_34 (0x00034 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_35 (0x00035 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_36 (0x00036 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_37 (0x00037 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_38 (0x00038 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_39 (0x00039 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_3A (0x0003A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_3B (0x0003B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_3C (0x0003C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_3D (0x0003D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_3E (0x0003E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_3F (0x0003F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_40 (0x00040 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_41 (0x00041 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_42 (0x00042 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_43 (0x00043 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_44 (0x00044 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_45 (0x00045 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_46 (0x00046 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_47 (0x00047 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_48 (0x00048 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_49 (0x00049 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_4A (0x0004A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_4B (0x0004B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_4C (0x0004C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_4D (0x0004D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_4E (0x0004E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_4F (0x0004F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_50 (0x00050 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_51 (0x00051 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_52 (0x00052 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_53 (0x00053 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_54 (0x00054 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_55 (0x00055 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_56 (0x00056 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_57 (0x00057 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_58 (0x00058 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_59 (0x00059 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_5A (0x0005A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_5B (0x0005B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_5C (0x0005C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_5D (0x0005D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_5E (0x0005E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_5F (0x0005F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_60 (0x00060 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_61 (0x00061 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_62 (0x00062 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_63 (0x00063 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_64 (0x00064 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_65 (0x00065 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_66 (0x00066 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_67 (0x00067 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_68 (0x00068 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_69 (0x00069 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_6A (0x0006A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_6B (0x0006B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_6C (0x0006C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_6D (0x0006D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_6E (0x0006E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_6F (0x0006F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_70 (0x00070 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_71 (0x00071 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_72 (0x00072 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_73 (0x00073 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_74 (0x00074 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_75 (0x00075 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_76 (0x00076 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_77 (0x00077 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_78 (0x00078 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_79 (0x00079 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_7A (0x0007A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_7B (0x0007B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_7C (0x0007C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_7D (0x0007D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_7E (0x0007E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_7F (0x0007F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_80 (0x00080 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_81 (0x00081 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_82 (0x00082 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_83 (0x00083 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_84 (0x00084 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_85 (0x00085 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_86 (0x00086 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_87 (0x00087 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_88 (0x00088 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_89 (0x00089 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_8A (0x0008A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_8B (0x0008B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_8C (0x0008C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_8D (0x0008D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_8E (0x0008E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_8F (0x0008F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_90 (0x00090 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_91 (0x00091 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_92 (0x00092 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_93 (0x00093 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_94 (0x00094 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_95 (0x00095 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_96 (0x00096 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_97 (0x00097 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_98 (0x00098 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_99 (0x00099 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_9A (0x0009A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_9B (0x0009B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_9C (0x0009C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_9D (0x0009D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_9E (0x0009E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_9F (0x0009F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A0 (0x000A0 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A1 (0x000A1 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A2 (0x000A2 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A3 (0x000A3 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A4 (0x000A4 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A5 (0x000A5 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A6 (0x000A6 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A7 (0x000A7 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A8 (0x000A8 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A9 (0x000A9 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_AA (0x000AA + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_AB (0x000AB + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_AC (0x000AC + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_AD (0x000AD + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_AE (0x000AE + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_AF (0x000AF + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B0 (0x000B0 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B1 (0x000B1 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B2 (0x000B2 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B3 (0x000B3 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B4 (0x000B4 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B5 (0x000B5 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B6 (0x000B6 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B7 (0x000B7 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B8 (0x000B8 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B9 (0x000B9 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_BA (0x000BA + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_BB (0x000BB + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_BC (0x000BC + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_BD (0x000BD + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_BE (0x000BE + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_BF (0x000BF + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C0 (0x000C0 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C1 (0x000C1 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C2 (0x000C2 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C3 (0x000C3 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C4 (0x000C4 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C5 (0x000C5 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C6 (0x000C6 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C7 (0x000C7 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C8 (0x000C8 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C9 (0x000C9 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_CA (0x000CA + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_CB (0x000CB + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_CC (0x000CC + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_CD (0x000CD + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_CE (0x000CE + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_CF (0x000CF + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D0 (0x000D0 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D1 (0x000D1 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D2 (0x000D2 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D3 (0x000D3 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D4 (0x000D4 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D5 (0x000D5 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D6 (0x000D6 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D7 (0x000D7 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D8 (0x000D8 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D9 (0x000D9 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_DA (0x000DA + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_DB (0x000DB + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_DC (0x000DC + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_DD (0x000DD + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_DE (0x000DE + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_DF (0x000DF + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E0 (0x000E0 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E1 (0x000E1 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E2 (0x000E2 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E3 (0x000E3 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E4 (0x000E4 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E5 (0x000E5 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E6 (0x000E6 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E7 (0x000E7 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E8 (0x000E8 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E9 (0x000E9 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_EA (0x000EA + cOCT6100_FATAL_BASE) + +#endif /* __OCT6100_ERRORS_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_events_inst.h b/xpp/oct612x/include/oct6100api/oct6100_events_inst.h new file mode 100644 index 0000000..323cd5b --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_events_inst.h @@ -0,0 +1,69 @@ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_events_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_events.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_events_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 12 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_EVENTS_INST_H__ +#define __OCT6100_EVENTS_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_TONE_EVENT_ +{ + UINT32 ulChannelHandle; + UINT32 ulUserChanId; + UINT32 ulToneDetected; /* Tone number of the tone detected. */ + UINT32 ulTimestamp; + UINT32 ulEventType; + UINT32 ulExtToneDetectionPort; + +} tOCT6100_API_TONE_EVENT, *tPOCT6100_API_TONE_EVENT; + +typedef struct _OCT6100_API_BUFFER_PLAYOUT_EVENT_ +{ + UINT32 ulChannelHandle; + UINT32 ulUserChanId; + UINT32 ulChannelPort; + UINT32 ulTimestamp; + UINT32 ulUserEventId; + UINT32 ulEventType; + +} tOCT6100_API_BUFFER_PLAYOUT_EVENT, *tPOCT6100_API_BUFFER_PLAYOUT_EVENT; + +#endif /* __OCT6100_EVENTS_INST_H__ */ + diff --git a/xpp/oct612x/include/oct6100api/oct6100_events_pub.h b/xpp/oct612x/include/oct6100api/oct6100_events_pub.h new file mode 100644 index 0000000..4ee131a --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_events_pub.h @@ -0,0 +1,111 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_events_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_events.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_events_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 14 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_EVENTS_PUB_H__ +#define __OCT6100_EVENTS_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_TONE_EVENT_ +{ + UINT32 ulChannelHndl; + UINT32 ulUserChanId; + + UINT32 ulToneDetected; + + UINT32 ulTimestamp; + UINT32 ulEventType; + + UINT32 ulExtToneDetectionPort; + +} tOCT6100_TONE_EVENT, *tPOCT6100_TONE_EVENT; + +typedef struct _OCT6100_EVENT_GET_TONE_ +{ + BOOL fMoreEvents; + BOOL fResetBufs; + + UINT32 ulMaxToneEvent; + UINT32 ulNumValidToneEvent; + + tPOCT6100_TONE_EVENT pToneEvent; + +} tOCT6100_EVENT_GET_TONE, *tPOCT6100_EVENT_GET_TONE; + +typedef struct _OCT6100_BUFFER_PLAYOUT_EVENT_ +{ + UINT32 ulChannelHndl; + UINT32 ulUserChanId; + UINT32 ulChannelPort; + + UINT32 ulTimestamp; + + UINT32 ulUserEventId; + UINT32 ulEventType; + +} tOCT6100_BUFFER_PLAYOUT_EVENT, *tPOCT6100_BUFFER_PLAYOUT_EVENT; + +typedef struct _OCT6100_BUFFER_PLAYOUT_GET_EVENT_ +{ + BOOL fMoreEvents; + BOOL fResetBufs; + + UINT32 ulMaxEvent; + UINT32 ulNumValidEvent; + + tPOCT6100_BUFFER_PLAYOUT_EVENT pBufferPlayoutEvent; + +} tOCT6100_BUFFER_PLAYOUT_GET_EVENT, *tPOCT6100_BUFFER_PLAYOUT_GET_EVENT; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100EventGetToneDef( + OUT tPOCT6100_EVENT_GET_TONE f_pEventGetTone ); +UINT32 Oct6100EventGetTone( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_EVENT_GET_TONE f_pEventGetTone ); + +UINT32 Oct6100BufferPlayoutGetEventDef( + OUT tPOCT6100_BUFFER_PLAYOUT_GET_EVENT f_pBufPlayoutGetEvent ); +UINT32 Oct6100BufferPlayoutGetEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_BUFFER_PLAYOUT_GET_EVENT f_pBufPlayoutGetEvent ); + +#endif /* __OCT6100_EVENTS_PUB_H__ */ + diff --git a/xpp/oct612x/include/oct6100api/oct6100_interrupts_inst.h b/xpp/oct612x/include/oct6100api/oct6100_interrupts_inst.h new file mode 100644 index 0000000..fc82cdd --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_interrupts_inst.h @@ -0,0 +1,134 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_interrupts_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_interrupts.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_interrupts_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 16 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_INTERRUPTS_INST_H__ +#define __OCT6100_INTERRUPTS_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_INTRPT_CONFIG_ +{ + /* The configuration of each group of interrupts. Each can have one of the + following values: + cOCT6100_INTRPT_DISABLE, + cOCT6100_INTRPT_NO_TIMEOUT, + cOCT6100_INTRPT_TIMEOUT. */ + UINT8 byFatalGeneralConfig; + UINT8 byFatalMemoryConfig; + UINT8 byErrorMemoryConfig; + UINT8 byErrorOverflowToneEventsConfig; + UINT8 byErrorH100Config; + + /* The timeout value for each interrupt group, if the corresponding + configuration variable is set to cOCT6100_INTRPT_TIMEOUT. This + value is kept in mclk cycles. */ + UINT32 ulFatalMemoryTimeoutMclk; + UINT32 ulErrorMemoryTimeoutMclk; + UINT32 ulErrorOverflowToneEventsTimeoutMclk; + UINT32 ulErrorH100TimeoutMclk; + +} tOCT6100_API_INTRPT_CONFIG, *tPOCT6100_API_INTRPT_CONFIG; + +typedef struct _OCT6100_API_INTRPT_MANAGE_ +{ + /* Number of mclk cycles in 1ms. */ + UINT32 ulNumMclkCyclesIn1Ms; + + /* Whether the mclk interrupt is active. */ + UINT8 fMclkIntrptActive; + UINT32 ulNextMclkIntrptTimeHigh; + UINT32 ulNextMclkIntrptTimeLow; + + /* Mclk time read from registers. */ + UINT32 ulRegMclkTimeHigh; + UINT32 ulRegMclkTimeLow; + + /* Used by the interrupt service routine. */ + UINT16 usRegister102h; + UINT16 usRegister202h; + UINT16 usRegister302h; + UINT16 usRegister502h; + UINT16 usRegister702h; + + /* The state of each interrupt group. Can be one of the following: + cOCT6100_INTRPT_ACTIVE, + cOCT6100_INTRPT_WILL_TIMEOUT, + cOCT6100_INTRPT_IN_TIMEOUT, + cOCT6100_INTRPT_WILL_DISABLED. */ + UINT16 byFatalGeneralState; + UINT16 byFatalMemoryState; + UINT16 byErrorMemoryState; + UINT16 byErrorOverflowToneEventsState; + UINT16 byErrorH100State; + + /* The time at which each disabled interrupt was disabled, in mclk cycles. */ + UINT32 ulFatalMemoryDisableMclkHigh; + UINT32 ulFatalMemoryDisableMclkLow; + UINT32 ulErrorMemoryDisableMclkHigh; + UINT32 ulErrorMemoryDisableMclkLow; + UINT32 ulErrorOverflowToneEventsDisableMclkHigh; + UINT32 ulErrorOverflowToneEventsDisableMclkLow; + UINT32 ulErrorH100DisableMclkHigh; + UINT32 ulErrorH100DisableMclkLow; + + /* The time at which each disabled interrupt group is to be reenabled, + in number of mclk cycles. */ + UINT32 ulFatalGeneralEnableMclkHigh; + UINT32 ulFatalGeneralEnableMclkLow; + UINT32 ulFatalMemoryEnableMclkHigh; + UINT32 ulFatalMemoryEnableMclkLow; + UINT32 ulErrorMemoryEnableMclkHigh; + UINT32 ulErrorMemoryEnableMclkLow; + UINT32 ulErrorOverflowToneEventsEnableMclkHigh; + UINT32 ulErrorOverflowToneEventsEnableMclkLow; + UINT32 ulErrorH100EnableMclkHigh; + UINT32 ulErrorH100EnableMclkLow; + + /* If this is set, buffer playout events are pending. */ + UINT8 fBufferPlayoutEventsPending; + /* If this is set, tone events are pending. */ + UINT8 fToneEventsPending; + + + + UINT8 fIsrCalled; + +} tOCT6100_API_INTRPT_MANAGE, *tPOCT6100_API_INTRPT_MANAGE; + +#endif /* __OCT6100_INTERRUPTS_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_interrupts_pub.h b/xpp/oct612x/include/oct6100api/oct6100_interrupts_pub.h new file mode 100644 index 0000000..a90fdcf --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_interrupts_pub.h @@ -0,0 +1,102 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_interrupts_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_interrupts.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_interrupts_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 23 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_INTERRUPTS_PUB_H__ +#define __OCT6100_INTERRUPTS_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_INTERRUPT_CONFIGURE_ +{ + UINT32 ulFatalGeneralConfig; + UINT32 ulFatalMemoryConfig; + + UINT32 ulErrorMemoryConfig; + UINT32 ulErrorOverflowToneEventsConfig; + UINT32 ulErrorH100Config; + + UINT32 ulFatalMemoryTimeout; + UINT32 ulErrorMemoryTimeout; + UINT32 ulErrorOverflowToneEventsTimeout; + UINT32 ulErrorH100Timeout; + +} tOCT6100_INTERRUPT_CONFIGURE, *tPOCT6100_INTERRUPT_CONFIGURE; + +typedef struct _OCT6100_INTERRUPT_FLAGS_ +{ + BOOL fFatalGeneral; + UINT32 ulFatalGeneralFlags; + + BOOL fFatalReadTimeout; + + BOOL fErrorRefreshTooLate; + BOOL fErrorPllJitter; + + BOOL fErrorOverflowToneEvents; + + BOOL fErrorH100OutOfSync; + BOOL fErrorH100ClkA; + BOOL fErrorH100ClkB; + BOOL fErrorH100FrameA; + + BOOL fToneEventsPending; + BOOL fBufferPlayoutEventsPending; + + BOOL fApiSynch; + + + +} tOCT6100_INTERRUPT_FLAGS, *tPOCT6100_INTERRUPT_FLAGS; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100InterruptConfigureDef( + OUT tPOCT6100_INTERRUPT_CONFIGURE f_pConfigInts ); +UINT32 Oct6100InterruptConfigure( + IN tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_INTERRUPT_CONFIGURE f_pConfigInts ); + +UINT32 Oct6100InterruptServiceRoutineDef( + OUT tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ); +UINT32 Oct6100InterruptServiceRoutine( + IN tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ); + +#endif /* __OCT6100_INTERRUPTS_PUB_H__ */ + diff --git a/xpp/oct612x/include/oct6100api/oct6100_mixer_inst.h b/xpp/oct612x/include/oct6100api/oct6100_mixer_inst.h new file mode 100644 index 0000000..1415e86 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_mixer_inst.h @@ -0,0 +1,86 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_mixer_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_mixer.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_mixer_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 13 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_MIXER_INST_H__ +#define __OCT6100_MIXER_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_MIXER_EVENT_ +{ + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Type of the event.*/ + UINT16 usEventType; + + /* Source channel index */ + UINT16 usSourceChanIndex; + + /* Destination channel index */ + UINT16 usDestinationChanIndex; + + /* Pointer to the next entry.*/ + UINT16 usNextEventPtr; + +} tOCT6100_API_MIXER_EVENT, *tPOCT6100_API_MIXER_EVENT; + + +typedef struct _OCT6100_API_COPY_EVENT_ +{ + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Count used to manage entry handles allocated to user. */ + UINT8 byEntryOpenCnt; + + /* Source + destination ports. */ + UINT8 bySourcePort; + UINT8 byDestinationPort; + + /* Index of the channels associated to this event.*/ + UINT16 usSourceChanIndex; + UINT16 usDestinationChanIndex; + + UINT16 usMixerEventIndex; + +} tOCT6100_API_COPY_EVENT, *tPOCT6100_API_COPY_EVENT; + + +#endif /* __OCT6100_MIXER_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_mixer_pub.h b/xpp/oct612x/include/oct6100api/oct6100_mixer_pub.h new file mode 100644 index 0000000..08aa28b --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_mixer_pub.h @@ -0,0 +1,77 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_mixer_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_mixer.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_mixer_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 7 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_MIXER_PUB_H__ +#define __OCT6100_MIXER_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_COPY_EVENT_CREATE_ +{ + PUINT32 pulCopyEventHndl; + + UINT32 ulSourceChanHndl; + UINT32 ulSourcePort; + + UINT32 ulDestinationChanHndl; + UINT32 ulDestinationPort; + +} tOCT6100_COPY_EVENT_CREATE, *tPOCT6100_COPY_EVENT_CREATE; + +typedef struct _OCT6100_COPY_EVENT_DESTROY_ +{ + UINT32 ulCopyEventHndl; + +} tOCT6100_COPY_EVENT_DESTROY, *tPOCT6100_COPY_EVENT_DESTROY; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100MixerCopyEventCreateDef( + OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate ); +UINT32 Oct6100MixerCopyEventCreate( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate ); + +UINT32 Oct6100MixerCopyEventDestroyDef( + OUT tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy ); +UINT32 Oct6100MixerCopyEventDestroy( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy ); + +#endif /* __OCT6100_MIXER_PUB_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_phasing_tsst_inst.h b/xpp/oct612x/include/oct6100api/oct6100_phasing_tsst_inst.h new file mode 100644 index 0000000..a2b2e27 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_phasing_tsst_inst.h @@ -0,0 +1,68 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_phasing_tsst_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_phasing_tsst.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_phasing_tsst_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 11 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_PHASING_TSST_INST_H__ +#define __OCT6100_PHASING_TSST_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_PHASING_TSST_ +{ + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Count used to manage entry handles allocated to user. */ + UINT8 byEntryOpenCnt; + + /* Count of number of resources connected in some way to this buffer. */ + UINT16 usDependencyCnt; + + /* TDM timeslot and stream where the counter is read. */ + UINT16 usStream; + UINT16 usTimeslot; + + /* Length of the phasing TSST counter. */ + UINT16 usPhasingLength; + + /* TSST control index where the counter comes from. */ + UINT16 usPhasingTsstIndex; + +} tOCT6100_API_PHASING_TSST, *tPOCT6100_API_PHASING_TSST; + +#endif /* __OCT6100_PHASING_TSST_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_phasing_tsst_pub.h b/xpp/oct612x/include/oct6100api/oct6100_phasing_tsst_pub.h new file mode 100644 index 0000000..b5af946 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_phasing_tsst_pub.h @@ -0,0 +1,78 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_phasing_tsst_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_phasing_tsst.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_phasing_tsst_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 10 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_PHASING_TSST_PUB_H__ +#define __OCT6100_PHASING_TSST_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_PHASING_TSST_OPEN_ +{ + PUINT32 pulPhasingTsstHndl; + + UINT32 ulPhasingLength; + UINT32 ulTimeslot; + UINT32 ulStream; + + + +} tOCT6100_PHASING_TSST_OPEN, *tPOCT6100_PHASING_TSST_OPEN; + +typedef struct _OCT6100_PHASING_TSST_CLOSE_ +{ + UINT32 ulPhasingTsstHndl; + +} tOCT6100_PHASING_TSST_CLOSE, *tPOCT6100_PHASING_TSST_CLOSE; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100PhasingTsstOpenDef( + OUT tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen ); +UINT32 Oct6100PhasingTsstOpen( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen ); + +UINT32 Oct6100PhasingTsstCloseDef( + OUT tPOCT6100_PHASING_TSST_CLOSE f_pPhasingTsstClose ); +UINT32 Oct6100PhasingTsstClose( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PHASING_TSST_CLOSE f_pPhasingTsstClose ); + +#endif /* __OCT6100_PHASING_TSST_PUB_H__ */ + diff --git a/xpp/oct612x/include/oct6100api/oct6100_playout_buf_inst.h b/xpp/oct612x/include/oct6100api/oct6100_playout_buf_inst.h new file mode 100644 index 0000000..046a639 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_playout_buf_inst.h @@ -0,0 +1,88 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_playout_buf_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_playout_buf.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_playout_buf_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 10 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_PLAYOUT_BUF_INST_H__ +#define __OCT6100_PLAYOUT_BUF_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +#define mOCT6100_GET_BUFFER_MEMORY_NODE_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE )(( PUINT8 )pSharedInfo + pSharedInfo->ulPlayoutBufMemoryNodeListOfst ); + +#define mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE )(( PUINT8 )pSharedInfo + pSharedInfo->ulPlayoutBufMemoryNodeListOfst)) + ulIndex; + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE_ +{ + /* Next node. */ + UINT32 ulNext; + + /* Previous node. */ + UINT32 ulPrevious; + + /* Start address of this node. */ + UINT32 ulStartAddress; + + /* Size of this node. */ + UINT32 ulSize; + + /* Allocated node? Free node? */ + UINT8 fAllocated; + +} tOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE, *tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE; + +typedef struct _OCT6100_API_BUFFER_ +{ + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Pcm law of the buffer. */ + UINT8 byBufferPcmLaw; + + /* Number of channels currently playing this buffer.*/ + UINT16 usDependencyCnt; + + /* Length of the buffer ( in bytes ).*/ + UINT32 ulBufferSize; + + /* Address in external memory of the buffer. */ + UINT32 ulBufferBase; + +} tOCT6100_API_BUFFER, *tPOCT6100_API_BUFFER; + +#endif /* __OCT6100_PLAYOUT_BUF_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_playout_buf_pub.h b/xpp/oct612x/include/oct6100api/oct6100_playout_buf_pub.h new file mode 100644 index 0000000..9fe0d6f --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_playout_buf_pub.h @@ -0,0 +1,183 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_playout_buf_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_playout_buf.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_playout_buf_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 21 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_PLAYOUT_BUF_PUB_H__ +#define __OCT6100_PLAYOUT_BUF_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_BUFFER_LOAD_ +{ + PUINT32 pulBufferIndex; /* Index identifying the buffer. */ + PUINT32 pulPlayoutFreeMemSize; /* Amount of free memory available for other buffers. */ + + PUINT8 pbyBufferPattern; /* A byte pointer pointing to a valid buffer to be loaded into the chip's external memory. */ + UINT32 ulBufferSize; /* Size of the buffer loaded into external memory. */ + + UINT32 ulBufferPcmLaw; /* Buffer PCM law. */ + +} tOCT6100_BUFFER_LOAD, *tPOCT6100_BUFFER_LOAD; + +typedef struct _OCT6100_BUFFER_LOAD_BLOCK_INIT_ +{ + PUINT32 pulBufferIndex; /* Index identifying the buffer. */ + PUINT32 pulPlayoutFreeMemSize; /* Amount of free memory available for other buffers. */ + + UINT32 ulBufferSize; /* Size of the buffer to be loaded in memory. This space will be reserved. */ + + UINT32 ulBufferPcmLaw; /* Buffer PCM law. */ + +} tOCT6100_BUFFER_LOAD_BLOCK_INIT, *tPOCT6100_BUFFER_LOAD_BLOCK_INIT; + +typedef struct _OCT6100_BUFFER_LOAD_BLOCK_ +{ + UINT32 ulBufferIndex; /* Index identifying the buffer. */ + + /* Offset, in bytes, of the first byte in the block to be loaded. */ + /* This offset is with respect to the beginning of the buffer. */ + /* This value must be modulo 2 */ + UINT32 ulBlockOffset; + + /* Size of the block to be loaded into external memory. */ + /* This value must be modulo 2. */ + UINT32 ulBlockLength; + + /* A pointer pointing to a valid buffer block to be loaded */ + /* into the chip's external memory. This is a pointer to the entire */ + /* buffer. The API uses the ulBlockOffset and ulBlockLength to index */ + /* within this buffer and obtain the block to be loaded. */ + PUINT8 pbyBufferPattern; + +} tOCT6100_BUFFER_LOAD_BLOCK, *tPOCT6100_BUFFER_LOAD_BLOCK; + +typedef struct _OCT6100_BUFFER_UNLOAD_ +{ + UINT32 ulBufferIndex; /* Index identifying the buffer. */ + +} tOCT6100_BUFFER_UNLOAD, *tPOCT6100_BUFFER_UNLOAD; + +typedef struct _OCT6100_BUFFER_PLAYOUT_ADD_ +{ + UINT32 ulChannelHndl; /* Echo cancelling channel on which to play the buffer. */ + + UINT32 ulBufferIndex; /* Index identifying the buffer. */ + + UINT32 ulPlayoutPort; /* Selected channel port where to play to tone. */ + UINT32 ulMixingMode; /* Weither or not the voice stream will be muted while playing the buffer. */ + + INT32 lGainDb; /* Gain applied to the buffer that will be played on the specified port. */ + + BOOL fRepeat; /* Use ulRepeatCount variable. */ + UINT32 ulRepeatCount; /* Number of times to repeat playing the selected buffer. */ + + UINT32 ulDuration; /* Duration in millisecond that this buffer should play. Setting this overrides fRepeat. */ + + UINT32 ulBufferLength; /* Length of the buffer to play (starting at the beginning), AUTO_SELECT for all. */ + +} tOCT6100_BUFFER_PLAYOUT_ADD, *tPOCT6100_BUFFER_PLAYOUT_ADD; + +typedef struct _OCT6100_BUFFER_PLAYOUT_START_ +{ + UINT32 ulChannelHndl; /* Echo cancelling channel on which to play the buffer. */ + UINT32 ulPlayoutPort; /* Selected channel port where to play to tone. */ + + BOOL fNotifyOnPlayoutStop; /* Check if the buffers have finished playing on this channel/port. */ + /* The events are queued in a soft buffer that the user must empty regularly. */ + UINT32 ulUserEventId; /* Returned to the user when the playout is finished and the user has set the fNotifyOnPlayoutStop flag. */ + + BOOL fAllowStartWhileActive; /* Use this to add buffers to something that is already playing on the channel/port. */ + +} tOCT6100_BUFFER_PLAYOUT_START, *tPOCT6100_BUFFER_PLAYOUT_START; + +typedef struct _OCT6100_BUFFER_PLAYOUT_STOP_ +{ + UINT32 ulChannelHndl; /* Echo cancelling channel on which to play the buffer. */ + UINT32 ulPlayoutPort; /* Selected channel port where to play to tone. */ + BOOL fStopCleanly; /* Whether or not the skip will be clean. */ + + PBOOL pfAlreadyStopped; /* Whether playout was already stopped or not. */ + PBOOL pfNotifyOnPlayoutStop; /* Whether the user chosed to receive an event on playout stop. */ + +} tOCT6100_BUFFER_PLAYOUT_STOP, *tPOCT6100_BUFFER_PLAYOUT_STOP; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100BufferPlayoutLoadDef( + OUT tPOCT6100_BUFFER_LOAD f_pBufferLoad ); +UINT32 Oct6100BufferPlayoutLoad( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD f_pBufferLoad ); + +UINT32 Oct6100BufferPlayoutLoadBlockInitDef( + OUT tPOCT6100_BUFFER_LOAD_BLOCK_INIT f_pBufferLoadBlockInit ); +UINT32 Oct6100BufferPlayoutLoadBlockInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD_BLOCK_INIT f_pBufferLoadBlockInit ); + +UINT32 Oct6100BufferPlayoutLoadBlockDef( + OUT tPOCT6100_BUFFER_LOAD_BLOCK f_pBufferLoadBlock ); +UINT32 Oct6100BufferPlayoutLoadBlock( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD_BLOCK f_pBufferLoadBlock ); + +UINT32 Oct6100BufferPlayoutUnloadDef( + OUT tPOCT6100_BUFFER_UNLOAD f_pBufferUnload ); +UINT32 Oct6100BufferPlayoutUnload( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_UNLOAD f_pBufferUnload ); + +UINT32 Oct6100BufferPlayoutAddDef( + OUT tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd ); +UINT32 Oct6100BufferPlayoutAdd( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd ); + +UINT32 Oct6100BufferPlayoutStartDef( + OUT tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart ); +UINT32 Oct6100BufferPlayoutStart( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart ); + +UINT32 Oct6100BufferPlayoutStopDef( + OUT tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop ); +UINT32 Oct6100BufferPlayoutStop( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop ); + +#endif /* __OCT6100_PLAYOUT_BUF_PUB_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_remote_debug_inst.h b/xpp/oct612x/include/oct6100api/oct6100_remote_debug_inst.h new file mode 100644 index 0000000..85a8d39 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_remote_debug_inst.h @@ -0,0 +1,73 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_remote_debug_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_remote_debug.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_remote_debug_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 6 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_REMOTE_DEBUG_INST_H__ +#define __OCT6100_REMOTE_DEBUG_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_REMOTE_DEBUG_INFO_ +{ + UINT32 ulSessionTreeOfst; + UINT32 ulSessionListOfst; + UINT32 ulSessionListHead; + UINT32 ulSessionListTail; + + UINT32 ulPktCacheOfst; + UINT32 ulDataBufOfst; + + UINT32 ulNumSessionsOpen; + UINT32 ulMaxSessionsOpen; + +} tOCT6100_API_REMOTE_DEBUG_INFO, *tPOCT6100_API_REMOTE_DEBUG_INFO; + +typedef struct _OCT6100_API_REMOTE_DEBUG_SESSION_ +{ + UINT32 ulSessionNum; + UINT32 ulTransactionNum; + UINT32 ulPktRetryNum; + UINT32 ulPktByteSize; + + UINT32 aulLastPktTime[ 2 ]; + UINT32 ulForwardLink; + UINT32 ulBackwardLink; + +} tOCT6100_API_REMOTE_DEBUG_SESSION, *tPOCT6100_API_REMOTE_DEBUG_SESSION; + +#endif /* __OCT6100_REMOTE_DEBUG_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_remote_debug_pub.h b/xpp/oct612x/include/oct6100api/oct6100_remote_debug_pub.h new file mode 100644 index 0000000..18a7e22 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_remote_debug_pub.h @@ -0,0 +1,64 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_remote_debug_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_remote_debug.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_remote_debug_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 6 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_REMOTE_DEBUG_PUB_H__ +#define __OCT6100_REMOTE_DEBUG_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_REMOTE_DEBUG_ +{ + PUINT32 pulReceivedPktPayload; + UINT32 ulReceivedPktLength; + + PUINT32 pulResponsePktPayload; + UINT32 ulMaxResponsePktLength; + UINT32 ulResponsePktLength; + +} tOCT6100_REMOTE_DEBUG, *tPOCT6100_REMOTE_DEBUG; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100RemoteDebugDef( + OUT tPOCT6100_REMOTE_DEBUG f_pRemoteDebug ); +UINT32 Oct6100RemoteDebug( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_REMOTE_DEBUG f_pRemoteDebug ); + +#endif /* __OCT6100_REMOTE_DEBUG_PUB_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_tlv_inst.h b/xpp/oct612x/include/oct6100api/oct6100_tlv_inst.h new file mode 100644 index 0000000..093ce0d --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_tlv_inst.h @@ -0,0 +1,72 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tlv_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_tlv.c. All elements defined in this file are for public + usage of the API. All instate elements are defined in the + oct6100_tlv_inst.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 7 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TLV_INST_H__ +#define __OCT6100_TLV_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_TLV_OFFSET_ +{ + /* The dword offset contain the number of dword from a base address to reach the desired dword. + + i.e. usDwordOffset = (total bit offset) / 32; */ + + UINT16 usDwordOffset; + + /* The bit offset will contain the bit offset required to right shift the DWORD read and obtain + the desired value. This field is depend on the field size. + + i.e. byBitOffset = 31 - ((total bit offset) % 32) - byFieldSize; */ + + UINT8 byBitOffset; + UINT8 byFieldSize; + +} tOCT6100_TLV_OFFSET, *tPOCT6100_TLV_OFFSET; + +typedef struct _OCT6100_TLV_TONE_INFO_ +{ + UINT32 ulToneID; + UINT32 ulDetectionPort; + + UINT8 aszToneName[ cOCT6100_TLV_MAX_TONE_NAME_SIZE ]; + + + +} tOCT6100_TLV_TONE_INFO, *tPOCT6100_TLV_TONE_INFO; + +#endif /* __OCT6100_TLV_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_tone_detection_inst.h b/xpp/oct612x/include/oct6100api/oct6100_tone_detection_inst.h new file mode 100644 index 0000000..1ee86fe --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_tone_detection_inst.h @@ -0,0 +1,46 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tone_detection_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_tone_detection_buf.c. All elements defined in this file are for + public usage of the API. All private elements are defined in the + oct6100_tone_detection_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 8 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TONE_DETECTION_INST_H__ +#define __OCT6100_TONE_DETECTION_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + + +#endif /* __OCT6100_TONE_DETECTION_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_tone_detection_pub.h b/xpp/oct612x/include/oct6100api/oct6100_tone_detection_pub.h new file mode 100644 index 0000000..cf28069 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_tone_detection_pub.h @@ -0,0 +1,74 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tone_detection_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_tone_detection.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_tone_detection_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 10 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TONE_DETECTION_PUB_H__ +#define __OCT6100_TONE_DETECTION_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_TONE_DETECTION_ENABLE_ +{ + UINT32 ulChannelHndl; + UINT32 ulToneNumber; + +} tOCT6100_TONE_DETECTION_ENABLE, *tPOCT6100_TONE_DETECTION_ENABLE; + +typedef struct _OCT6100_TONE_DETECTION_DISABLE_ +{ + UINT32 ulChannelHndl; + UINT32 ulToneNumber; + BOOL fDisableAll; + +} tOCT6100_TONE_DETECTION_DISABLE, *tPOCT6100_TONE_DETECTION_DISABLE; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ToneDetectionEnableDef( + OUT tPOCT6100_TONE_DETECTION_ENABLE f_pBufferLoad ); +UINT32 Oct6100ToneDetectionEnable( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TONE_DETECTION_ENABLE f_pBufferLoad ); + +UINT32 Oct6100ToneDetectionDisableDef( + OUT tPOCT6100_TONE_DETECTION_DISABLE f_pBufferUnload ); +UINT32 Oct6100ToneDetectionDisable( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TONE_DETECTION_DISABLE f_pBufferUnload ); + +#endif /* __OCT6100_TONE_DETECTION_PUB_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_tsi_cnct_inst.h b/xpp/oct612x/include/oct6100api/oct6100_tsi_cnct_inst.h new file mode 100644 index 0000000..9eb23ba --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_tsi_cnct_inst.h @@ -0,0 +1,70 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tsi_cnct_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_tsi_cnct.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_tsi_cnct_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 9 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TSI_CNCT_INST_H__ +#define __OCT6100_TSI_CNCT_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_TSI_CNCT_ +{ + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Count used to manage entry handles allocated to user. */ + UINT8 byEntryOpenCnt; + + /* Input PCM law. */ + UINT8 byInputPcmLaw; + + /* TSI chariot memory entry. */ + UINT16 usTsiMemIndex; + + /* Input and output timeslot information. */ + UINT16 usInputTimeslot; + UINT16 usInputStream; + + UINT16 usOutputTimeslot; + UINT16 usOutputStream; + + /* Internal info for quick access to structures associated to this TSI cnct. */ + UINT16 usInputTsstIndex; + UINT16 usOutputTsstIndex; + +} tOCT6100_API_TSI_CNCT, *tPOCT6100_API_TSI_CNCT; + +#endif /* __OCT6100_TSI_CNCT_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_tsi_cnct_pub.h b/xpp/oct612x/include/oct6100api/oct6100_tsi_cnct_pub.h new file mode 100644 index 0000000..c030468 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_tsi_cnct_pub.h @@ -0,0 +1,76 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tsi_cnct_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_tsi_cnct.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_tsi_cnct_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 11 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TSI_CNCT_PUB_H__ +#define __OCT6100_TSI_CNCT_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_TSI_CNCT_OPEN_ +{ + PUINT32 pulTsiCnctHndl; + + UINT32 ulInputTimeslot; + UINT32 ulInputStream; + UINT32 ulOutputTimeslot; + UINT32 ulOutputStream; + +} tOCT6100_TSI_CNCT_OPEN, *tPOCT6100_TSI_CNCT_OPEN; + +typedef struct _OCT6100_TSI_CNCT_CLOSE_ +{ + UINT32 ulTsiCnctHndl; + +} tOCT6100_TSI_CNCT_CLOSE, *tPOCT6100_TSI_CNCT_CLOSE; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100TsiCnctOpenDef( + OUT tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen ); +UINT32 Oct6100TsiCnctOpen( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen ); + +UINT32 Oct6100TsiCnctCloseDef( + OUT tPOCT6100_TSI_CNCT_CLOSE f_pTsiCnctClose ); +UINT32 Oct6100TsiCnctClose( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TSI_CNCT_CLOSE f_pTsiCnctClose ); + +#endif /* __OCT6100_TSI_CNCT_PUB_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_tsst_inst.h b/xpp/oct612x/include/oct6100api/oct6100_tsst_inst.h new file mode 100644 index 0000000..6b9fe77 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_tsst_inst.h @@ -0,0 +1,55 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tsst_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_tsst.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_tsst_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 5 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TSST_INST_H__ +#define __OCT6100_TSST_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_TSST_ENTRY_ +{ + UINT16 usTsstMemoryIndex; /* Index in the TSST memory of the TSST */ + UINT16 usTsstValue; /* Tsst value given by the user. */ + /* bit 5:0 = stream value, bit 13:6 = timeslot value. */ + + UINT16 usNextEntry; /* Pointer to the next entry in the list. */ + +} tOCT6100_API_TSST_ENTRY, *tPOCT6100_API_TSST_ENTRY; + +#endif /* __OCT6100_TSST_INST_H__ */ diff --git a/xpp/oct612x/include/octdef.h b/xpp/oct612x/include/octdef.h new file mode 100644 index 0000000..7e534b7 --- /dev/null +++ b/xpp/oct612x/include/octdef.h @@ -0,0 +1,120 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octdef.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Common system definitions. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 12 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCTDEF_H__ +#define __OCTDEF_H__ + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __KERNEL__ +#include +#endif + +/***************************** INCLUDE FILES *******************************/ + +/*-------------------------------------------------------------------------- + Get Platform Dependency headers +----------------------------------------------------------------------------*/ +#include "octosdependant.h" + + +/*-------------------------------------------------------------------------- + Common Type definitions +----------------------------------------------------------------------------*/ +#include "octtype.h" + +/***************************** DEFINES *************************************/ + +/* List of functions to skip compiling since we don't use them */ +#include "digium_unused.h" + + + +/*-------------------------------------------------------------------------- + Miscellaneous constants +----------------------------------------------------------------------------*/ + +#ifndef PROTO +#define PROTO extern +#endif + +/* Generic return codes. */ +#define cOCTDEF_RC_OK 0 /* Generic Ok */ +#define cOCTDEF_RC_ERROR 1 /* Generic Error */ + +/* Default return values of all OCTAPI functions. */ +#ifndef GENERIC_OK +#define GENERIC_OK 0x00000000 +#endif + +#ifndef GENERIC_ERROR +#define GENERIC_ERROR 0x00000001 +#endif + +#ifndef GENERIC_BAD_PARAM +#define GENERIC_BAD_PARAM 0x00000002 +#endif + +/* Defines of boolean expressions (TRUE/FALSE) */ +#ifndef FALSE +#define FALSE (BOOL)0 +#endif + +#ifndef TRUE +#define TRUE (BOOL)1 +#endif + +/*-------------------------------------------------------------------------- + DLL Import-Export +----------------------------------------------------------------------------*/ + +#ifdef OCT_WINENV +#define DLLIMP __declspec( dllimport ) +#define DLLEXP __declspec( dllexport ) +#else +#define DLLIMP +#define DLLEXP +#endif + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __OCTDEF_H__ */ diff --git a/xpp/oct612x/include/octmac.h b/xpp/oct612x/include/octmac.h new file mode 100644 index 0000000..2e930ae --- /dev/null +++ b/xpp/oct612x/include/octmac.h @@ -0,0 +1,98 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octmac.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Common macro definitions. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 14 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#ifndef __OCTMAC_H__ +#define __OCTMAC_H__ + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** DEFINES *************************************/ + +/* Combine l & h to form a 32 bit quantity. */ +#define mMAKEULONG(l, h) ((ULONG)(((USHORT)(l)) | (((ULONG)((USHORT)(h))) << 16))) + +#define mLOUCHAR(w) ((UCHAR)(w)) +#define mHIUCHAR(w) ((UCHAR)(((USHORT)(w) >> 8) & 0xff)) +#define mLOUSHORT(l) ((USHORT)((ULONG)l)) +#define mHIUSHORT(l) ((USHORT)(((ULONG)(l) >> 16) & 0xffff)) +#define mLOSHORT(l) ((SHORT)((ULONG)l)) +#define mHISHORT(l) ((SHORT)(((ULONG)(l) >> 16) & 0xffff)) + +/* Combine l & h to form a 16 bit quantity. */ +#define mMAKEUSHORT(l, h) (((USHORT)(l)) | ((USHORT)(h)) << 8) +#define mMAKESHORT(l, h) ((SHORT)mMAKEUSHORT(l, h)) + +/* Extract high and low order parts of 16 and 32 bit quantity */ +#define mLOBYTE(w) mLOUCHAR(w) +#define mHIBYTE(w) mHIUCHAR(w) +#define mMAKELONG(l, h) ((LONG)mMAKEULONG(l, h)) + +/*-------------------------------------------------------------------------- + Bite conversion macro +----------------------------------------------------------------------------*/ +#define mSWAP_INT16(x) mMAKEUSHORT( mHIBYTE(x), mLOBYTE(x) ) +#define mSWAP_INT32(x) mMAKEULONG( mSWAP_INT16(mHIUSHORT(x)), mSWAP_INT16(mLOUSHORT(x)) ) + + +/* Cast any variable to an instance of the specified type. */ +#define mMAKETYPE(v, type) (*((type *)&v)) + +/* Calculate the byte offset of a field in a structure of type type. */ +#define mFIELDOFFSET(type, field) ((UINT32)&(((type *)0)->field)) +#define mCOUNTOF(array) (sizeof(array)/sizeof(array[0])) + +#define mMAX(a,b) (((a) > (b)) ? (a) : (b)) +#define mMIN(a,b) (((a) < (b)) ? (a) : (b)) + +#define mDIM(x) (sizeof(x) / sizeof(x[0])) + +#define mFROMDIGIT(ch) ((ch) - 0x30) /* digit to char */ +#define mTODIGIT(ch) ((ch) + 0x30) /* int to char */ + +#define mISLEAP(a) ( !( a % 400 ) || ( ( a % 100 ) && !( a % 4 ) ) ) + +#define mFOREVER for( ;; ) + +#define mROUND_TO_NEXT_4( a ) ( ((a) % 4) ? ( (a) + 4 - ((a)%4) ) : (a) ) + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __OCTMAC_H__ */ diff --git a/xpp/oct612x/include/octosdependant.h b/xpp/oct612x/include/octosdependant.h new file mode 100644 index 0000000..d7008a4 --- /dev/null +++ b/xpp/oct612x/include/octosdependant.h @@ -0,0 +1,170 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octosdependant.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file is included to set target-specific constants. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 18 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCTOSDEPENDANT_H__ +#define __OCTOSDEPENDANT_H__ + + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + + + +/***************************************************************************** + + Known define values + + MSDEV: + WIN32 == WINDOWS 32 bit app + __WIN32__ == WINDOWS 32 bit app + _Windows == WINDOWS 16 bit app + + _WINDOWS == Windows application .. not console + _DLL == Dll Application + _CONSOLE == Console Application .. no windows + + BORLANDC + __TURBOC__ == Turbo Compiler + __BORLANDC__ == Borland compiler + __OS2__ == Borland OS2 compiler + _Windows == Windows 16 bit app + + GCC Compiler + __GNUC__ == GCC Compiler + __unix__ == Unix system + __vax__ == Unix system + unix == Unix system + vax == vax system + + TORNADO + _VXWORKS_ == VXWORK + + ECOS/CYGWIN + _ECOS_ == eCos + + SOLARIS + _SOLARIS_ == Solaris + +*****************************************************************************/ + +/* Machine endian type */ + +#define OCT_MACH_LITTLE_ENDIAN 1 +#define OCT_MACH_BIG_ENDIAN 2 + +/* Try to find current OCT_MACH_ENDIAN from compiler define values */ +#if !defined( MACH_TYPE_BIG_ENDIAN ) && !defined( MACH_TYPE_LITTLE_ENDIAN ) + /* Does GNU defines the endian ? */ + #if defined(__GNU_C__) + #if defined(_BIG_ENDIAN) || defined(__BIG_ENDIAN__) + #define OCT_MACH_ENDIAN OCT_MACH_BIG_ENDIAN + #elif defined(_LITTLE_ENDIAN) || defined(__LITTLE_ENDIAN__) + #define OCT_MACH_ENDIAN OCT_MACH_LITTLE_ENDIAN + #endif + #endif + + /* Try with cpu type */ + #if !defined(OCT_MACH_ENDIAN) + /* Look for intel */ + #if defined( _M_IX86 ) + #define OCT_MACH_ENDIAN OCT_MACH_LITTLE_ENDIAN + /* Look for PowerPC */ + #elif defined( _M_MPPC ) || defined( _M_PPC ) || defined(PPC) || defined(__PPC) || defined(_ARCH_PPC) + #define OCT_MACH_ENDIAN OCT_MACH_BIG_ENDIAN + /* Look for Blackfin */ + #elif defined( __bfin__ ) + #define OCT_MACH_ENDIAN OCT_MACH_LITTLE_ENDIAN + #elif defined( CPU ) + #if CPU==PPC860 || CPU==SIMNT + #define OCT_MACH_ENDIAN OCT_MACH_BIG_ENDIAN + #else + #define OCT_MACH_ENDIAN OCT_MACH_LITTLE_ENDIAN + #endif + #else + #define OCT_MACH_ENDIAN OCT_MACH_LITTLE_ENDIAN + #endif + #endif +#else + #if defined( MACH_TYPE_BIG_ENDIAN ) + #define OCT_MACH_ENDIAN OCT_MACH_BIG_ENDIAN + #else + #define OCT_MACH_ENDIAN OCT_MACH_LITTLE_ENDIAN + #endif +#endif + +/* Find system type if not already defined */ +#if !defined( OCT_NTDRVENV ) && !defined( OCT_VXENV ) && !defined( OCT_WINENV ) + +#if defined( WIN32 ) || defined( __WIN32__ ) || defined( _WIN32_ ) || defined( WIN32S ) + /* Verif if building a win32 driver */ + #if ( defined( WIN32 ) && WIN32==100 ) + #define OCT_NTDRVENV + #else + #define OCT_WINENV + #endif +#elif defined( _VXWORKS_ ) + #define OCT_VXENV +#elif defined( _ECOS_ ) +#ifndef OCT_ECOSENV + #define OCT_ECOSENV +#endif /* OCT_ECOSENV */ +#elif defined( _SOLARIS_ ) + #define OCT_SOLARISENV +#elif defined( _LINUX_ ) + #define OCT_LINUXENV +#else + /* Unknown environment */ + #define OCT_UNKNOWNENV +#endif /* WIN env */ + +#endif /* Already defined */ + +#if defined( __KERNEL__ ) && defined( OCT_LINUXENV ) +#define OCT_LINUXDRVENV +#endif + +#ifdef _DEBUG +#define OCT_OPT_USER_DEBUG +#endif + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __OCTOSDEPENDANT_H__ */ diff --git a/xpp/oct612x/include/octrpc/oct6100_rpc_protocol.h b/xpp/oct612x/include/octrpc/oct6100_rpc_protocol.h new file mode 100644 index 0000000..fcee581 --- /dev/null +++ b/xpp/oct612x/include/octrpc/oct6100_rpc_protocol.h @@ -0,0 +1,348 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_rpc_protocol.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines and prototypes related to the OCT6100 RPC + protocol for exchanging debug commands. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 6 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_RPC_PROTOCOL_H__ +#define __OCT6100_RPC_PROTOCOL_H__ + +/***************************** DEFINES *************************************/ + +#define cOCTRPC_INTERFACE_VERSION 0x00010002 + +/* Octasic commands. */ +#define cOCT6100_RPC_CHIP_LIST 0xFF000000 +#define cOCT6100_RPC_CHIP_CHOICE 0xFF000001 +#define cOCT6100_RPC_ENV_DISCONNECT 0xFF000002 + +/* Commands */ +/* Read commands */ +#define cOCT6100_RPC_READ_WORD 0x00000000 +#define cOCT6100_RPC_READ_BURST 0x00000001 +#define cOCT6100_RPC_READ_DEBUG 0x00000002 +#define cOCT6100_RPC_READ_ARRAY 0x00000003 +#define cOCT6100_RPC_API_DISCONNECT 0x00000004 + +/* Write commands */ +#define cOCT6100_RPC_WRITE_WORD 0x00000010 +#define cOCT6100_RPC_WRITE_BURST 0x00000011 +#define cOCT6100_RPC_WRITE_SMEAR 0x00000012 +#define cOCT6100_RPC_WRITE_INC 0x00000013 + +/* Debug commands.*/ +#define cOCT6100_RPC_SET_HOT_CHANNEL 0x00000014 +#define cOCT6100_RPC_GET_DEBUG_CHAN_INDEX 0x00000015 + +#define cOCTRPC_UNKNOWN_COMMAND_NUM 0xFFFFFFFF + +/* Errors */ +#define cOCT6100_RPCERR_OK 0x00000000 +#define cOCT6100_RPCERR_INVALID_COMMAND_NUMBER 0x00000001 +#define cOCT6100_RPCERR_INVALID_COMMAND_PAYLOAD 0x00000002 +#define cOCT6100_RPCERR_INVALID_COMMAND_LENGTH 0x00000003 + + +/***************************** TYPES ***************************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_READ_WORD + +Description: Command structure for the read of one word. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulAddress Address at which to read. +OUT ulReadData The word read, returned. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_READ_WORD_ +{ + UINT32 IN ulAddress; + UINT32 OUT ulReadData; + +} tOCT6100_RPC_READ_WORD, *tPOCT6100_RPC_READ_WORD; + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_READ_BURST + +Description: Command structure for a read burst. The burst starts at the + given address and reads the specified number of consecutive + words. + + Whereas every command structure uses a complete dword for every + member, irrespective of the size of data unit needed, this + structure does not do so for the read data. To save bandwidth + the read data words are returned two per dword. + +Example packet: 31 16 15 0 + ------------------------------------------- + | ulAddress = 0x100 | + ------------------------------------------- + | ulBurstLength = 0x3 | + ------------------------------------------- + aulReadData -> | D0 | D1 | + ------------------------------------------- + | D2 | xx | + ------------------------------------------- + + Dy is the read data at ulAddress + 2 * y. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulAddress Address at which to read. +IN ulBurstLength The number of consecutive words to be read. +OUT aulReadData The read data returned. The dwords of the structure + starting at this address are arranged as indicated in + the example packet above. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_READ_BURST_ +{ + UINT32 IN ulAddress; + UINT32 IN ulBurstLength; + UINT32 OUT aulReadData[ 1 ]; + +} tOCT6100_RPC_READ_BURST, *tPOCT6100_RPC_READ_BURST; + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_READ_ARRAY + +Description: Command structure for a variable number of reads. The reads do + not have to be at contiguous addresses. + + Whereas every command structure uses a complete dword for every + member, irrespective of the size of data unit needed, this + structure does not do so for the read data. To save bandwidth + the read data words are returned two per dword, and the + parity bits are returned 16 per dword (two parity bits per read + access). + +Example packet: 31 16 15 0 + ------------------------------------------- + | ulArrayLength = 0x3 | + ------------------------------------------- + aulArrayData ->| A0 | + ------------------------------------------- + | A1 | + ------------------------------------------- + | A2 | + ------------------------------------------- + | D0 | D1 | + ------------------------------------------- + | D2 | xx | + ------------------------------------------- + + Ay is the address for access y. + Dy is the read data at Ay. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulArrayLength Number of reads to do. +IN OUT aulArrayData The addresses at which to read (IN) and the read data + returned (OUT). The dwords of the command structure + starting at this address are arranged as indicated in + the example packet above. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_READ_ARRAY +{ + UINT32 IN ulArrayLength; + UINT32 IN OUT aulArrayData[ 1 ]; + +} tOCT6100_RPC_READ_ARRAY, *tPOCT6100_RPC_READ_ARRAY; + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_WRITE_WORD + +Description: Command structure for the write of one word. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulAddress Address at which to write. +IN ulWriteData The word to write. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_WRITE_WORD_ +{ + UINT32 IN ulAddress; + UINT32 IN ulParity; + UINT32 IN ulWriteData; + +} tOCT6100_RPC_WRITE_WORD, *tPOCT6100_RPC_WRITE_WORD; + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_WRITE_SMEAR + +Description: Command structure for the write of one word at one or many + consecutive addresses. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulAddress Address of first write. +IN ulSmearLength Number of consecutive addresses to write. +IN ulWriteData The word to write at each address. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_WRITE_SMEAR_ +{ + UINT32 IN ulAddress; + UINT32 IN ulSmearLength; + UINT32 IN ulParity; + UINT32 IN ulWriteData; + +} tOCT6100_RPC_WRITE_SMEAR, *tPOCT6100_RPC_WRITE_SMEAR; + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_WRITE_INC + +Description: Command structure for the write of an incremental pattern at + one or many consecutive addresses. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulAddress Address of first write. +IN ulIncLength Number of consecutive addresses to write. +IN ulWriteData The first word of the incremental pattern. For each + consecutive write the word will be incremented by 1. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_WRITE_INC_ +{ + UINT32 IN ulAddress; + UINT32 IN ulIncLength; + UINT32 IN ulParity; + UINT32 IN ulWriteData; + +} tOCT6100_RPC_WRITE_INC, *tPOCT6100_RPC_WRITE_INC; + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_WRITE_BURST + +Description: Command structure for a write burst. The burst starts at the + given address and writes a given word for each address. + + Whereas every command structure uses a complete dword for every + member, irrespective of the size of data unit needed, this + structure does not do so for the write data. To save bandwidth + the write data words are sent two per dword. + +Example packet: 31 16 15 0 + ------------------------------------------- + | ulAddress = 0x100 | + ------------------------------------------- + | ulBurstLength = 0x3 | + ------------------------------------------- + aulWriteData ->| D0 | D1 | + ------------------------------------------- + | D2 | xx | + ------------------------------------------- + + Dy is the write data for ulAddress + 2 * y. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulAddress First address at which to write. +IN ulBurstLength The number of consecutive addresses to be write. +IN aulWriteData The write data words. The dwords of the structure + starting at this address are arranged as indicated in + the example packet above. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_WRITE_BURST_ +{ + UINT32 IN ulAddress; + UINT32 IN ulBurstLength; + UINT32 IN ulParity; + UINT32 IN aulWriteData[ 1 ]; + +} tOCT6100_RPC_WRITE_BURST, *tPOCT6100_RPC_WRITE_BURST; + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_SET_HOT_CHANNEL + +Description: Command structure to set the hot channel. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulDebugChannel Index of the channel to debug. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_SET_HOT_CHANNEL_ +{ + UINT32 IN ulHotChannel; + UINT32 IN ulPcmLaw; + +} tOCT6100_RPC_SET_HOT_CHANNEL, *tPOCT6100_RPC_SET_HOT_CHANNEL; + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_GET_DEBUG_CHAN_INDEX + +Description: Command structure to get the debug channel index used by the API. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulDebugChannel Index of the channel to debug. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_GET_DEBUG_CHAN_INDEX_ +{ + UINT32 OUT ulDebugChanIndex; + +} tOCT6100_RPC_GET_DEBUG_CHAN_INDEX, *tPOCT6100_RPC_GET_DEBUG_CHAN_INDEX; + +#endif /* __OCT6100_RPC_PROTOCOL_H__ */ diff --git a/xpp/oct612x/include/octrpc/rpc_protocol.h b/xpp/oct612x/include/octrpc/rpc_protocol.h new file mode 100644 index 0000000..24e1596 --- /dev/null +++ b/xpp/oct612x/include/octrpc/rpc_protocol.h @@ -0,0 +1,115 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: rpc_protocol.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + +This file contains RPC related definitions and prototypes. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 23 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __RPC_PROTOCOL_H__ +#define __RPC_PROTOCOL_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +#define cOCTRPC_ENDIAN_DETECT 0x27182819 +#define cOCTRPC_ENDIAN_DETECT_BYTE_W 0x19 +#define cOCTRPC_ENDIAN_DETECT_BYTE_X 0x28 +#define cOCTRPC_ENDIAN_DETECT_BYTE_Y 0x18 +#define cOCTRPC_ENDIAN_DETECT_BYTE_Z 0x27 +#define cOCTRPC_ECHO_PROTOCOL 0x00000000 + +#define cOCTRPC_MIN_PACKET_BYTE_LENGTH (sizeof( tOCTRPC_OGRDTP_HEADER )) +#define cOCTRPC_FIRST_COMMAND_BYTE_OFFSET (sizeof( tOCTRPC_OGRDTP_HEADER ) + sizeof( tOCTRPC_INTERFACE_HEADER )) +#define cOCTRPC_GENERIC_HEADERS_BYTE_SIZE (sizeof( tOCTRPC_OGRDTP_HEADER ) + sizeof( tOCTRPC_INTERFACE_HEADER ) + sizeof( tOCTRPC_COMMAND_HEADER )) +#define cOCTRPC_MAX_PACKET_BYTE_LENGTH 32768 + +/* Protocol versions */ +#define cOCTRPC_PROTOCOL_V1_0 0x00010000 +#define cOCTRPC_PROTOCOL_V1_1 0x00010001 +#define cOCTRPC_PROTOCOL_V1_2 0x00010002 +#define cOCTRPC_PROTOCOL_V1_3 0x00010003 +#define cOCTRPC_OCTASIC_PROTOCOL_V1_0 0xFF010000 +#define cOCTRPC_OCTASIC_PROTOCOL_V1_1 0xFF010001 +#define cOCTRPC_OCTASIC_PROTOCOL_V1_2 0xFF010002 +#define cOCTRPC_OCTASIC_PROTOCOL_V1_3 0xFF010003 + +/* Chips */ +#define cOCTRPC_OCT8304_INTERFACE 0x00000000 +#define cOCTRPC_OCT6100_INTERFACE 0x00000001 + +/* Timeout values. */ +#define cOCTRPC_SESSION_TIMEOUT 30 + +/* Generic errors */ +#define cOCTRPC_RDBGERR_OK 0x00000000 +#define cOCTRPC_RDBGERR_NO_ANSWER 0xFFFF0000 +#define cOCTRPC_RDBGERR_ALL_SESSIONS_OPEN 0xFFFF0001 +#define cOCTRPC_RDBGERR_PROTOCOL_NUMBER 0xFFFF0002 +#define cOCTRPC_RDBGERR_NO_COMMAND_HEADER 0xFFFF0003 +#define cOCTRPC_RDBGERR_INTERFACE_TYPE 0xFFFF0004 +#define cOCTRPC_RDBGERR_INTERFACE_VERSION 0xFFFF0005 +#define cOCTRPC_RDBGERR_INVALID_PACKET_LENGTH 0xFFFF0006 +#define cOCTRPC_RDBGERR_INVALID_COMMAND_LENGTH 0xFFFF0007 +#define cOCTRPC_RDBGERR_INVALID_COMMAND_NUMBER 0xFFFF0008 +#define cOCTRPC_RDBGERR_PACKET_TOO_LARGE 0xFFFF0009 +#define cOCTRPC_RDBGERR_LIST_EMPTY 0xFFFF000A + +#define cOCTRPC_RDBGERR_FATAL 0xFFFFFFFF + + +/***************************** TYPES ***************************************/ + +typedef struct _OCTRPC_OGRDTP_HEADER_ +{ + UINT32 IN ulEndianDetect; + UINT32 IN ulDebugSessionNum; + UINT32 IN ulTransactionNum; + UINT32 IN ulPktRetryNum; + UINT32 IN ulPktByteSize; + UINT32 IN ulChecksum; + UINT32 OUT ulParsingError; + UINT32 IN ulRpcProtocolNum; + +} tOCTRPC_OGRDTP_HEADER, *tPOCTRPC_OGRDTP_HEADER; + +typedef struct _OCTRPC_INTERFACE_HEADER_ +{ + UINT32 IN ulInterfaceType; + UINT32 IN ulInterfaceVersion; + +} tOCTRPC_INTERFACE_HEADER, *tPOCTRPC_INTERFACE_HEADER; + +typedef struct _OCTRPC_COMMAND_HEADER_ +{ + UINT32 IN ulCommandByteSize; + UINT32 IN OUT ulRpcCommandNum; + UINT32 OUT ulFunctionResult; + +} tOCTRPC_COMMAND_HEADER, *tPOCTRPC_COMMAND_HEADER; + +#endif /* __RPC_PROTOCOL_H__ */ diff --git a/xpp/oct612x/include/octtype.h b/xpp/oct612x/include/octtype.h new file mode 100644 index 0000000..7bed715 --- /dev/null +++ b/xpp/oct612x/include/octtype.h @@ -0,0 +1,159 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octtype.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file defines the base storage types. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 18 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#ifndef __OCTTYPE_H__ +#define __OCTTYPE_H__ + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*-------------------------------------------------------------------------- + Include target-specific header if available +----------------------------------------------------------------------------*/ +#if defined( OCT_NTDRVENV ) + #include "octtypentdrv.h" /* All NT driver typedef */ +#elif defined( OCT_WINENV ) + #include "octtypewin.h" /* All Win32 typedef */ +#elif defined( OCT_VXENV ) + #include "octtypevx.h" /* All VxWorks typedef */ +#else +/*-------------------------------------------------------------------------- + No target-specific header available +----------------------------------------------------------------------------*/ + +#ifdef SZ +#undef SZ +#endif + +/***************************** DEFINES *************************************/ +/* 16-bit integer */ +typedef unsigned short UINT16; +typedef signed short INT16; +typedef unsigned short *PUINT16; +typedef signed short *PINT16; + +/* 8-bit integer */ +typedef unsigned char UINT8; +typedef signed char INT8; +typedef signed char OCT_INT8; +typedef unsigned char *PUINT8; +typedef signed char *PINT8; + + +/* 32 bit integer */ +typedef unsigned int UINT32; +typedef signed int INT32; +typedef INT32 * PINT32; +typedef UINT32 * PUINT32; + +/* Long integer */ +typedef signed long LONG; +typedef unsigned long ULONG; +typedef long * PLONG; +typedef unsigned long * PULONG; + +/* Short integer */ +typedef short SHORT; +typedef unsigned short USHORT; +typedef short * PSHORT; +typedef unsigned short *PUSHORT; + +/* 8-bit integer*/ +typedef unsigned char BYTE; +typedef BYTE * PBYTE; +typedef unsigned char UCHAR; + +/* Character and strings */ +typedef char CHAR; +typedef CHAR SZ; +typedef CHAR * PSZ; +typedef CHAR * PCHAR; + +/* Double integers */ +typedef double DOUBLE; +typedef double * PDOUBLE; +typedef float FLOAT; +typedef float * PFLOAT; + +typedef void VOID; +typedef void * PVOID; + +/* Booleans */ +typedef int BOOL; +typedef BOOL * PBOOL; + +/* Integers */ +typedef int INT; +typedef int * PINT; +typedef unsigned int UINT; +typedef unsigned int * PUINT; + +/* Define pseudo-keywords IN and OUT if not defined yet */ +#ifndef IN +#define IN /* IN param */ +#endif + +#ifndef OUT +#define OUT /* OUT param */ +#endif + +/* LONG LONG */ +#define LLONG signed long long +#define PLLONG signed long long * +#define ULLONG unsigned long long +#define PULLONG unsigned long long * + +#ifndef OPT +#define OPT /* OPT param */ +#endif + +typedef PSZ * PPSZ; + +#if defined(__FreeBSD__) +#include +#else +#include +#endif + +#endif + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __OCTTYPE_H__ */ diff --git a/xpp/oct612x/include/octtypevx.h b/xpp/oct612x/include/octtypevx.h new file mode 100644 index 0000000..6588ae2 --- /dev/null +++ b/xpp/oct612x/include/octtypevx.h @@ -0,0 +1,132 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octtypevx.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file defines the base storage types for the VxWorks environment. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 9 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCTTYPEVX_H__ +#define __OCTTYPEVX_H__ + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vxWorks.h" + +/* 16-bit pointer integer */ +typedef unsigned short *PUINT16; +typedef signed short *PINT16; + +/* 8-bit integer pointer */ +typedef unsigned char *PUINT8; +typedef signed char *PINT8; + +/* 32-bit integer pointer */ +typedef INT32 * PINT32; +typedef UINT32 * PUINT32; + +/* Long integer pointer */ +/*Intel library for file system definition*/ +#ifndef DATATYPE_H +typedef long LONG; +#endif +typedef long * PLONG; +typedef unsigned long * PULONG; + +/* Short integer pointer */ +typedef short SHORT; +typedef short * PSHORT; +typedef unsigned short *PUSHORT; + +/* 8-bit integer*/ +#if (CPU!=SIMNT) && !defined(DATATYPE_H) +typedef char BYTE; +#endif + + +typedef BYTE * PBYTE; + +/* Character and strings */ +/*Intel library for file system definition*/ +#ifndef DATATYPE_H +typedef char CHAR; +#endif +typedef char * PCHAR; +typedef CHAR SZ; +typedef CHAR * PSZ; +typedef signed char OCT_INT8; + +/* Double integers */ +typedef double DOUBLE; +typedef double * PDOUBLE; +typedef float FLOAT; +typedef float * PFLOAT; + +typedef void * PVOID; + +/* Booleans */ +typedef BOOL * PBOOL; + +/* Integers */ +typedef int INT; +typedef int * PINT; +typedef unsigned int PUINT; + +/* Define pseudo-keywords IN and OUT if not defined yet */ +#ifndef IN +#define IN /* IN param */ +#endif + +#ifndef OUT +#define OUT /* OUT param */ +#endif + +/* LONG LONG */ +#define LLONG signed long long +#define PLLONG signed long long * +#define ULLONG unsigned long long +#define PULLONG unsigned long long * + +#ifndef OPT +#define OPT /* OPT param */ +#endif + +typedef PSZ * PPSZ; + + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* __OCTTYPEVX_H__ */ diff --git a/xpp/oct612x/include/octtypewin.h b/xpp/oct612x/include/octtypewin.h new file mode 100644 index 0000000..8bdd690 --- /dev/null +++ b/xpp/oct612x/include/octtypewin.h @@ -0,0 +1,100 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octtypewin.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file defines the base storage types for the Windows environment. + Includes the Windows definition file and add the missing ones here. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 16 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCTTYPEWIN_H__ +#define __OCTTYPEWIN_H__ + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ +#define WIN32_LEAN_AND_MEAN /* just get the base type definition from Windows */ +#include + +/* Disable argument not used warning */ +#pragma warning( disable : 4100 ) +/* Disable Level 4 warning: nonstandard extension used : translation unit is empty */ +#pragma warning( disable : 4206 ) + +#ifdef __cplusplus +extern "C" { +#endif + +/* 16-bit integer */ +typedef unsigned short UINT16; +typedef signed short INT16; +typedef unsigned short *PUINT16; +typedef signed short *PINT16; + +/* 8-bit integer */ +typedef unsigned char UINT8; +typedef signed char INT8; +typedef signed char OCT_INT8; +typedef unsigned char *PUINT8; +typedef signed char *PINT8; + +typedef double DOUBLE; + + +/* 32 bit integer */ +#if ( defined( _MSC_VER ) && _MSC_VER == 1100 ) +/* MFC5 compiler does not define UINT32 */ +typedef unsigned int UINT32; +typedef signed int INT32; +typedef INT32 * PINT32; +typedef UINT32 * PUINT32; +#endif /* _MSC_VER */ + +/* LONG LONG */ +#define LLONG signed __int64 +#define PLLONG signed __int64 * +#define ULLONG unsigned __int64 +#define PULLONG unsigned __int64 * + +/* Double integers */ +typedef double DOUBLE; +typedef double * PDOUBLE; +typedef float FLOAT; +typedef float * PFLOAT; + +#ifndef OPT +#define OPT /* OPT param */ +#endif + +typedef PSZ * PPSZ; + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* __OCTTYPEWIN_H__ */ diff --git a/xpp/oct612x/octasic-helper b/xpp/oct612x/octasic-helper new file mode 100755 index 0000000..ab100d1 --- /dev/null +++ b/xpp/oct612x/octasic-helper @@ -0,0 +1,39 @@ +#!/bin/sh + +# +# Jeffrey C. Ollie +# +# $1 == information requested +# $2 == path to octasic directory +# + +APIDIR=$2/octdeviceapi/oct6100api/oct6100_api + +case $1 in + objects) + echo $APIDIR/oct6100_adpcm_chan.o \ + $APIDIR/oct6100_channel.o \ + $APIDIR/oct6100_chip_open.o \ + $APIDIR/oct6100_chip_stats.o \ + $APIDIR/oct6100_conf_bridge.o \ + $APIDIR/oct6100_debug.o \ + $APIDIR/oct6100_events.o \ + $APIDIR/oct6100_interrupts.o \ + $APIDIR/oct6100_memory.o \ + $APIDIR/oct6100_miscellaneous.o \ + $APIDIR/oct6100_mixer.o \ + $APIDIR/oct6100_phasing_tsst.o \ + $APIDIR/oct6100_playout_buf.o \ + $APIDIR/oct6100_remote_debug.o \ + $APIDIR/oct6100_tlv.o \ + $APIDIR/oct6100_tone_detection.o \ + $APIDIR/oct6100_tsi_cnct.o \ + $APIDIR/oct6100_tsst.o \ + $2/apilib/bt/octapi_bt0.o \ + $2/apilib/largmath/octapi_largmath.o \ + $2/apilib/llman/octapi_llman.o + ;; + cflags) + echo -I$2/include -I$2/octdeviceapi -I$2/octdeviceapi/oct6100api + ;; +esac diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_adpcm_chan_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_adpcm_chan_priv.h new file mode 100644 index 0000000..a078070 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_adpcm_chan_priv.h @@ -0,0 +1,131 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_adpcm_chan_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_adpcm_chan.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_adpcm_chan_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 7 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_ADPCM_CHAN_PRIV_H__ +#define __OCT6100_ADPCM_CHAN_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/* ADPCM channel list pointer macros. */ +#define mOCT6100_GET_ADPCM_CHAN_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_ADPCM_CHAN )(( PUINT8 )pSharedInfo + pSharedInfo->ulAdpcmChanListOfst ); + +#define mOCT6100_GET_ADPCM_CHAN_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_ADPCM_CHAN )(( PUINT8 )pSharedInfo + pSharedInfo->ulAdpcmChanListOfst)) + ulIndex; + +#define mOCT6100_GET_ADPCM_CHAN_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulAdpcmChanAllocOfst); + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetAdpcmChanSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100ApiAdpcmChanSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + + +UINT32 Oct6100AdpcmChanOpenSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ); + +UINT32 Oct6100ApiCheckAdpcmChanParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ); + +UINT32 Oct6100ApiReserveAdpcmChanResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen, + OUT PUINT16 f_pusTsiChanIndex, + OUT PUINT16 f_pusAdpcmMemIndex, + OUT PUINT16 f_pusTsiMemIndex, + OUT PUINT16 f_pusInputTsstIndex, + OUT PUINT16 f_pusOutputTsstIndex ); + +UINT32 Oct6100ApiWriteAdpcmChanStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen, + IN UINT16 f_usAdpcmMemIndex, + IN UINT16 f_usTsiMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ); + +UINT32 Oct6100ApiUpdateAdpcmChanEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen, + IN UINT16 f_usTsiChanIndex, + IN UINT16 f_usAdpcmMemIndex, + IN UINT16 f_usTsiMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ); + +UINT32 Oct6100AdpcmChanCloseSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose ); + +UINT32 Oct6100ApiAssertAdpcmChanParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose, + OUT PUINT16 f_pusTsiChanIndex, + OUT PUINT16 f_pusAdpcmMemIndex, + OUT PUINT16 f_pusTsiMemIndex, + OUT PUINT16 f_pusInputTsstIndex, + OUT PUINT16 f_pusOutputTsstIndex ); + +UINT32 Oct6100ApiInvalidateAdpcmChanStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usAdpcmChanIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ); + +UINT32 Oct6100ApiReleaseAdpcmChanResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsiChanIndex, + IN UINT16 f_usAdpcmMemIndex, + IN UINT16 f_usTsiMemIndex ); + +UINT32 Oct6100ApiReserveAdpcmChanEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusAdpcmChanIndex ); + +UINT32 Oct6100ApiReleaseAdpcmChanEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usAdpcmChanIndex ); + +#endif /* __OCT6100_ADPCM_CHAN_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_adpcm_chan.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_adpcm_chan.c new file mode 100644 index 0000000..aec4c5e --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_adpcm_chan.c @@ -0,0 +1,1237 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_adpcm_chan.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains functions used to open and close ADPCM channels. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 16 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_adpcm_chan_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_adpcm_chan_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_tsst_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_adpcm_chan_priv.h" + +/**************************** PUBLIC FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100AdpcmChanOpen + +Description: This function opens an ADPCM channel between two TDM timeslots. + This channel will perform ADPCM compression or decompression + depending on the channel mode. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pAdpcmChanOpen Pointer to ADPCM channel open structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100AdpcmChanOpenDef +UINT32 Oct6100AdpcmChanOpenDef( + tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ) +{ + f_pAdpcmChanOpen->pulChanHndl = NULL; + + f_pAdpcmChanOpen->ulInputTimeslot = cOCT6100_INVALID_TIMESLOT; + f_pAdpcmChanOpen->ulInputStream = cOCT6100_INVALID_STREAM; + f_pAdpcmChanOpen->ulInputNumTssts = 1; + f_pAdpcmChanOpen->ulInputPcmLaw = cOCT6100_PCM_U_LAW; + + f_pAdpcmChanOpen->ulOutputTimeslot = cOCT6100_INVALID_TIMESLOT; + f_pAdpcmChanOpen->ulOutputStream = cOCT6100_INVALID_STREAM; + f_pAdpcmChanOpen->ulOutputPcmLaw = cOCT6100_PCM_U_LAW; + f_pAdpcmChanOpen->ulOutputNumTssts = 1; + + f_pAdpcmChanOpen->ulChanMode = cOCT6100_ADPCM_ENCODING; + f_pAdpcmChanOpen->ulEncodingRate = cOCT6100_G726_32KBPS; + f_pAdpcmChanOpen->ulDecodingRate = cOCT6100_G726_32KBPS; + + f_pAdpcmChanOpen->ulAdpcmNibblePosition = cOCT6100_ADPCM_IN_LOW_BITS; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100AdpcmChanOpen +UINT32 Oct6100AdpcmChanOpen( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100AdpcmChanOpenSer( f_pApiInstance, f_pAdpcmChanOpen ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100AdpcmChanClose + +Description: This function closes an opened ADPCM channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pAdpcmChanClose Pointer to ADPCM channel close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100AdpcmChanCloseDef +UINT32 Oct6100AdpcmChanCloseDef( + tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose ) +{ + f_pAdpcmChanClose->ulChanHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100AdpcmChanClose +UINT32 Oct6100AdpcmChanClose( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100AdpcmChanCloseSer( f_pApiInstance, f_pAdpcmChanClose ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetAdpcmChanSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of the ADPCM memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pOpenChip Pointer to chip configuration struct. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetAdpcmChanSwSizes +UINT32 Oct6100ApiGetAdpcmChanSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + + /* Determine the amount of memory required for the API ADPCM channel list.*/ + f_pInstSizes->ulAdpcmChannelList = f_pOpenChip->ulMaxAdpcmChannels * sizeof( tOCT6100_API_ADPCM_CHAN ); + + if ( f_pOpenChip->ulMaxAdpcmChannels > 0 ) + { + /* Calculate memory needed for ADPCM memory allocation */ + ulResult = OctapiLlmAllocGetSize( f_pOpenChip->ulMaxAdpcmChannels, &f_pInstSizes->ulAdpcmChannelAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_48; + } + else + { + f_pInstSizes->ulAdpcmChannelAlloc = 0; + } + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulAdpcmChannelList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulAdpcmChannelAlloc, ulTempVar ) + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAdpcmChanSwInit + +Description: Initializes all elements of the instance structure associated + to the ADPCM memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAdpcmChanSwInit +UINT32 Oct6100ApiAdpcmChanSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_API_ADPCM_CHAN pChannelsTsiList; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulMaxAdpcmChannels; + PVOID pAdpcmChannelsAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Initialize the ADPCM channel API list.*/ + ulMaxAdpcmChannels = pSharedInfo->ChipConfig.usMaxAdpcmChannels; + + /* Set all entries in the ADPCM channel list to unused. */ + mOCT6100_GET_ADPCM_CHAN_LIST_PNT( pSharedInfo, pChannelsTsiList ) + + /* Clear the memory */ + Oct6100UserMemSet( pChannelsTsiList, 0x00, sizeof(tOCT6100_API_ADPCM_CHAN) * ulMaxAdpcmChannels ); + + /* Initialize the ADPCM channel allocation structures to "all free". */ + if ( ulMaxAdpcmChannels > 0 ) + { + mOCT6100_GET_ADPCM_CHAN_ALLOC_PNT( pSharedInfo, pAdpcmChannelsAlloc ) + + ulResult = OctapiLlmAllocInit( &pAdpcmChannelsAlloc, ulMaxAdpcmChannels ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_BD; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100AdpcmChanOpenSer + +Description: Opens an ADPCM channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pAdpcmChanOpen Pointer to an ADPCM channel open structure + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100AdpcmChanOpenSer +UINT32 Oct6100AdpcmChanOpenSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ) +{ + UINT16 usAdpcmChanIndex; + UINT16 usTsiMemIndex; + UINT16 usAdpcmMemIndex; + UINT16 usInputTsstIndex; + UINT16 usOutputTsstIndex; + UINT32 ulResult; + + /* Check the user's configuration of the ADPCM channel open structure for errors. */ + ulResult = Oct6100ApiCheckAdpcmChanParams( f_pApiInstance, f_pAdpcmChanOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the ADPCM channel. */ + ulResult = Oct6100ApiReserveAdpcmChanResources( f_pApiInstance, f_pAdpcmChanOpen, &usAdpcmChanIndex, &usAdpcmMemIndex, &usTsiMemIndex, &usInputTsstIndex, &usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write all necessary structures to activate the ADPCM channel. */ + ulResult = Oct6100ApiWriteAdpcmChanStructs( f_pApiInstance, f_pAdpcmChanOpen, usAdpcmMemIndex, usTsiMemIndex, usInputTsstIndex, usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the ADPCM channel entry in the API list. */ + ulResult = Oct6100ApiUpdateAdpcmChanEntry( f_pApiInstance, f_pAdpcmChanOpen, usAdpcmChanIndex, usAdpcmMemIndex, usTsiMemIndex, usInputTsstIndex, usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckAdpcmChanParams + +Description: Checks the user's ADPCM channel open configuration for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pAdpcmChanOpen Pointer to ADPCM channel open configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckAdpcmChanParams +UINT32 Oct6100ApiCheckAdpcmChanParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ) +{ + UINT32 ulResult; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxAdpcmChannels == 0 ) + return cOCT6100_ERR_ADPCM_CHAN_DISABLED; + + if ( f_pAdpcmChanOpen->pulChanHndl == NULL ) + return cOCT6100_ERR_ADPCM_CHAN_INVALID_HANDLE; + + /* Check the input TDM streams, timeslots component for errors. */ + if ( f_pAdpcmChanOpen->ulInputNumTssts != 1 && + f_pAdpcmChanOpen->ulInputNumTssts != 2 ) + return cOCT6100_ERR_ADPCM_CHAN_INPUT_NUM_TSSTS; + + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + f_pAdpcmChanOpen->ulInputNumTssts, + f_pAdpcmChanOpen->ulInputTimeslot, + f_pAdpcmChanOpen->ulInputStream, + cOCT6100_INPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_ADPCM_CHAN_INPUT_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_ADPCM_CHAN_INPUT_STREAM; + } + else + { + return ulResult; + } + } + + if( f_pAdpcmChanOpen->ulInputPcmLaw != cOCT6100_PCM_U_LAW && + f_pAdpcmChanOpen->ulInputPcmLaw != cOCT6100_PCM_A_LAW ) + return cOCT6100_ERR_ADPCM_CHAN_INPUT_PCM_LAW; + + /* Check the output TDM streams, timeslots component for errors. */ + if ( f_pAdpcmChanOpen->ulOutputNumTssts != 1 && + f_pAdpcmChanOpen->ulOutputNumTssts != 2 ) + return cOCT6100_ERR_ADPCM_CHAN_OUTPUT_NUM_TSSTS; + + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + f_pAdpcmChanOpen->ulOutputNumTssts, + f_pAdpcmChanOpen->ulOutputTimeslot, + f_pAdpcmChanOpen->ulOutputStream, + cOCT6100_OUTPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_ADPCM_CHAN_OUTPUT_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_ADPCM_CHAN_OUTPUT_STREAM; + } + else + { + return ulResult; + } + } + if( f_pAdpcmChanOpen->ulOutputPcmLaw != cOCT6100_PCM_U_LAW && + f_pAdpcmChanOpen->ulOutputPcmLaw != cOCT6100_PCM_A_LAW ) + return cOCT6100_ERR_ADPCM_CHAN_OUTPUT_PCM_LAW; + + /* Now, check the channel mode. */ + if ( f_pAdpcmChanOpen->ulChanMode != cOCT6100_ADPCM_ENCODING && + f_pAdpcmChanOpen->ulChanMode != cOCT6100_ADPCM_DECODING ) + return cOCT6100_ERR_ADPCM_CHAN_MODE; + + if ( f_pAdpcmChanOpen->ulChanMode == cOCT6100_ADPCM_ENCODING ) + { + /* Check the encoding rate. */ + if ( ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G711_64KBPS ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G726_40KBPS ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G726_32KBPS ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G726_24KBPS ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G726_16KBPS ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_40KBPS_4_1 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_40KBPS_3_2 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_40KBPS_2_3 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_32KBPS_4_0 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_32KBPS_3_1 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_32KBPS_2_2 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_24KBPS_3_0 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_24KBPS_2_1 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_16KBPS_2_0 ) ) + return cOCT6100_ERR_ADPCM_CHAN_ENCODING_RATE; + } + else /* if ( f_pAdpcmChanOpen->ulChanMode != cOCT6100_ADPCM_DECODING ) */ + { + /* Check the decoding rate. */ + if ( f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G711_64KBPS && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G726_40KBPS && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G726_32KBPS && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G726_24KBPS && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G726_16KBPS && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G726_ENCODED && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G711_G726_ENCODED && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G727_2C_ENCODED && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G727_3C_ENCODED && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G727_4C_ENCODED && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G711_G727_2C_ENCODED && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G711_G727_3C_ENCODED && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G711_G727_4C_ENCODED ) + return cOCT6100_ERR_ADPCM_CHAN_DECODING_RATE; + + /* Make sure that two timeslots are allocated if PCM-ECHO encoded is selected. */ + if ( (f_pAdpcmChanOpen->ulDecodingRate == cOCT6100_G711_G726_ENCODED || + f_pAdpcmChanOpen->ulDecodingRate == cOCT6100_G711_G727_2C_ENCODED || + f_pAdpcmChanOpen->ulDecodingRate == cOCT6100_G711_G727_3C_ENCODED || + f_pAdpcmChanOpen->ulDecodingRate == cOCT6100_G711_G727_4C_ENCODED ) && + f_pAdpcmChanOpen->ulInputNumTssts != 2 ) + return cOCT6100_ERR_ADPCM_CHAN_INCOMPATIBLE_NUM_TSSTS; + } + + /* Check the nibble position. */ + if ( f_pAdpcmChanOpen->ulAdpcmNibblePosition != cOCT6100_ADPCM_IN_LOW_BITS && + f_pAdpcmChanOpen->ulAdpcmNibblePosition != cOCT6100_ADPCM_IN_HIGH_BITS ) + return cOCT6100_ERR_ADPCM_CHAN_ADPCM_NIBBLE_POSITION; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveAdpcmChanResources + +Description: Reserves all resources needed for the new ADPCM channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pAdpcmChanOpen Pointer to ADPCM channel configuration structure. +f_pusAdpcmChanIndex Allocated entry in ADPCM channel list. +f_pusAdpcmMemIndex Allocated entry in the ADPCM control memory. +f_pusTsiMemIndex Allocated entry in the TSI chariot memory. +f_pusInputTsstIndex TSST memory index of the input samples. +f_pusOutputTsstIndex TSST memory index of the output samples. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveAdpcmChanResources +UINT32 Oct6100ApiReserveAdpcmChanResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen, + OUT PUINT16 f_pusAdpcmChanIndex, + OUT PUINT16 f_pusAdpcmMemIndex, + OUT PUINT16 f_pusTsiMemIndex, + OUT PUINT16 f_pusInputTsstIndex, + OUT PUINT16 f_pusOutputTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + UINT32 ulTempVar; + BOOL fAdpcmChanEntry = FALSE; + BOOL fAdpcmMemEntry = FALSE; + BOOL fTsiMemEntry = FALSE; + BOOL fInputTsst = FALSE; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Reserve an entry in the ADPCM channel list. */ + ulResult = Oct6100ApiReserveAdpcmChanEntry( f_pApiInstance, f_pusAdpcmChanIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fAdpcmChanEntry = TRUE; + + /* Find a TSI memory entry.*/ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, f_pusTsiMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fTsiMemEntry = TRUE; + + /* Find a conversion memory entry. */ + ulResult = Oct6100ApiReserveConversionMemEntry( f_pApiInstance, f_pusAdpcmMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fAdpcmMemEntry = TRUE; + + /* Reserve the input TSST entry. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + f_pAdpcmChanOpen->ulInputTimeslot, + f_pAdpcmChanOpen->ulInputStream, + f_pAdpcmChanOpen->ulInputNumTssts, + cOCT6100_INPUT_TSST, + f_pusInputTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fInputTsst = TRUE; + + /* Reserve the output TSST entry. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + f_pAdpcmChanOpen->ulOutputTimeslot, + f_pAdpcmChanOpen->ulOutputStream, + f_pAdpcmChanOpen->ulOutputNumTssts, + cOCT6100_OUTPUT_TSST, + f_pusOutputTsstIndex, + NULL ); + } + } + } + else + { + /* Return an error other than a fatal error. */ + ulResult = cOCT6100_ERR_ADPCM_CHAN_NO_MORE_TSI_AVAILABLE; + } + } + + if ( ulResult != cOCT6100_ERR_OK ) + { + if( fAdpcmChanEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseAdpcmChanEntry( f_pApiInstance, *f_pusAdpcmChanIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fTsiMemEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, *f_pusTsiMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fAdpcmMemEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, *f_pusAdpcmMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fInputTsst == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + f_pAdpcmChanOpen->ulInputTimeslot, + f_pAdpcmChanOpen->ulInputStream, + f_pAdpcmChanOpen->ulInputNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteAdpcmChanStructs + +Description: Performs all the required structure writes to configure the + new ADPCM channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pAdpcmChanOpen Pointer to ADPCM channel configuration structure. +f_pusAdpcmChanIndex Allocated entry in ADPCM channel list. +f_pusAdpcmMemIndex Allocated entry in the ADPCM control memory. +f_pusTsiMemIndex Allocated entry in the TSI chariot memory. +f_pusInputTsstIndex TSST memory index of the input samples. +f_pusOutputTsstIndex TSST memory index of the output samples. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteAdpcmChanStructs +UINT32 Oct6100ApiWriteAdpcmChanStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen, + IN UINT16 f_usAdpcmMemIndex, + IN UINT16 f_usTsiMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + UINT32 ulCompType = 0; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*------------------------------------------------------------------------------*/ + /* Configure the TSST control memory. */ + + /* Set the input TSST control entry. */ + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_usInputTsstIndex, + f_usTsiMemIndex, + f_pAdpcmChanOpen->ulInputPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the output TSST control entry. */ + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_usOutputTsstIndex, + f_pAdpcmChanOpen->ulAdpcmNibblePosition, + f_pAdpcmChanOpen->ulOutputNumTssts, + f_usTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + + /*------------------------------------------------------------------------------*/ + /* Configure the ADPCM memory. */ + + if ( f_pAdpcmChanOpen->ulChanMode == cOCT6100_ADPCM_ENCODING ) + { + switch( f_pAdpcmChanOpen->ulEncodingRate ) + { + case cOCT6100_G711_64KBPS: + + if ( f_pAdpcmChanOpen->ulOutputPcmLaw == cOCT6100_PCM_U_LAW ) + ulCompType = 0x4; + else /* if ( f_pAdpcmChanOpen->ulOutputPcmLaw != cOCT6100_PCM_U_LAW ) */ + ulCompType = 0x5; + break; + case cOCT6100_G726_40KBPS: ulCompType = 0x3; break; + case cOCT6100_G726_32KBPS: ulCompType = 0x2; break; + case cOCT6100_G726_24KBPS: ulCompType = 0x1; break; + case cOCT6100_G726_16KBPS: ulCompType = 0x0; break; + case cOCT6100_G727_40KBPS_4_1: ulCompType = 0xD; break; + case cOCT6100_G727_40KBPS_3_2: ulCompType = 0xA; break; + case cOCT6100_G727_40KBPS_2_3: ulCompType = 0x6; break; + case cOCT6100_G727_32KBPS_4_0: ulCompType = 0xE; break; + case cOCT6100_G727_32KBPS_3_1: ulCompType = 0xB; break; + case cOCT6100_G727_32KBPS_2_2: ulCompType = 0x7; break; + case cOCT6100_G727_24KBPS_3_0: ulCompType = 0xC; break; + case cOCT6100_G727_24KBPS_2_1: ulCompType = 0x8; break; + case cOCT6100_G727_16KBPS_2_0: ulCompType = 0x9; break; + } + + ulResult = Oct6100ApiWriteEncoderMemory( f_pApiInstance, + f_usAdpcmMemIndex, + ulCompType, + f_usTsiMemIndex, + FALSE, + f_pAdpcmChanOpen->ulAdpcmNibblePosition, + cOCT6100_INVALID_INDEX, + cOCT6100_INVALID_VALUE, + cOCT6100_INVALID_VALUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else /* if ( f_pAdpcmChanOpen->ulChanMode != cOCT6100_ADPCM_DECODING ) */ + { + switch( f_pAdpcmChanOpen->ulDecodingRate ) + { + case cOCT6100_G711_64KBPS: ulCompType = 0x8; break; + case cOCT6100_G726_40KBPS: ulCompType = 0x3; break; + case cOCT6100_G726_32KBPS: ulCompType = 0x2; break; + case cOCT6100_G726_24KBPS: ulCompType = 0x1; break; + case cOCT6100_G726_16KBPS: ulCompType = 0x0; break; + case cOCT6100_G727_2C_ENCODED: ulCompType = 0x4; break; + case cOCT6100_G727_3C_ENCODED: ulCompType = 0x5; break; + case cOCT6100_G727_4C_ENCODED: ulCompType = 0x6; break; + case cOCT6100_G726_ENCODED: ulCompType = 0x9; break; + case cOCT6100_G711_G726_ENCODED: ulCompType = 0xA; break; + case cOCT6100_G711_G727_2C_ENCODED: ulCompType = 0xC; break; + case cOCT6100_G711_G727_3C_ENCODED: ulCompType = 0xD; break; + case cOCT6100_G711_G727_4C_ENCODED: ulCompType = 0xE; break; + } + + ulResult = Oct6100ApiWriteDecoderMemory( f_pApiInstance, + f_usAdpcmMemIndex, + ulCompType, + f_usTsiMemIndex, + f_pAdpcmChanOpen->ulOutputPcmLaw, + f_pAdpcmChanOpen->ulAdpcmNibblePosition ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateAdpcmChanEntry + +Description: Updates the new ADPCM channel in the ADPCM channel list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pAdpcmChanOpen Pointer to ADPCM channel open configuration structure. +f_usAdpcmChanIndex Allocated entry in the ADPCM channel list. +f_usAdpcmMemIndex Allocated entry in ADPCM memory. +f_usTsiMemIndex Allocated entry in TSI chariot memory. +f_usInputTsstIndex TSST control memory index of the input TSST. +f_usOutputTsstIndex TSST control memory index of the output TSST. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateAdpcmChanEntry +UINT32 Oct6100ApiUpdateAdpcmChanEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen, + IN UINT16 f_usAdpcmChanIndex, + IN UINT16 f_usAdpcmMemIndex, + IN UINT16 f_usTsiMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ) +{ + tPOCT6100_API_ADPCM_CHAN pAdpcmChanEntry; + + /*------------------------------------------------------------------------------*/ + /* Obtain a pointer to the new ADPCM channel's list entry. */ + + mOCT6100_GET_ADPCM_CHAN_ENTRY_PNT( f_pApiInstance->pSharedInfo, pAdpcmChanEntry, f_usAdpcmChanIndex ) + + /* Copy the buffer's configuration and allocated resources. */ + pAdpcmChanEntry->usInputTimeslot = (UINT16)( f_pAdpcmChanOpen->ulInputTimeslot & 0xFFFF ); + pAdpcmChanEntry->usInputStream = (UINT16)( f_pAdpcmChanOpen->ulInputStream & 0xFFFF ); + pAdpcmChanEntry->byInputNumTssts = (UINT8)( f_pAdpcmChanOpen->ulInputNumTssts & 0xFF ); + pAdpcmChanEntry->byInputPcmLaw = (UINT8)( f_pAdpcmChanOpen->ulInputPcmLaw & 0xFF ); + + pAdpcmChanEntry->usOutputTimeslot = (UINT16)( f_pAdpcmChanOpen->ulOutputTimeslot & 0xFFFF ); + pAdpcmChanEntry->usOutputStream = (UINT16)( f_pAdpcmChanOpen->ulOutputStream & 0xFFFF ); + pAdpcmChanEntry->byOutputNumTssts = (UINT8)( f_pAdpcmChanOpen->ulOutputNumTssts & 0xFF ); + pAdpcmChanEntry->byOutputPcmLaw = (UINT8)( f_pAdpcmChanOpen->ulOutputPcmLaw & 0xFF ); + + /* Store hardware related information. */ + pAdpcmChanEntry->usTsiMemIndex = f_usTsiMemIndex; + pAdpcmChanEntry->usAdpcmMemIndex = f_usAdpcmMemIndex; + pAdpcmChanEntry->usInputTsstIndex = f_usInputTsstIndex; + pAdpcmChanEntry->usOutputTsstIndex = f_usOutputTsstIndex; + + /* Form handle returned to user. */ + *f_pAdpcmChanOpen->pulChanHndl = cOCT6100_HNDL_TAG_ADPCM_CHANNEL | (pAdpcmChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_usAdpcmChanIndex; + + /* Finally, mark the ADPCM channel as opened. */ + pAdpcmChanEntry->fReserved = TRUE; + + /* Increment the number of ADPCM channel opened. */ + f_pApiInstance->pSharedInfo->ChipStats.usNumberAdpcmChans++; + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100AdpcmChanCloseSer + +Description: Closes an ADPCM channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pAdpcmChanClose Pointer to ADPCM channel close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100AdpcmChanCloseSer +UINT32 Oct6100AdpcmChanCloseSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose ) +{ + UINT16 usAdpcmChanIndex; + UINT16 usTsiMemIndex; + UINT16 usAdpcmMemIndex; + UINT16 usInputTsstIndex; + UINT16 usOutputTsstIndex; + UINT32 ulResult; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertAdpcmChanParams( f_pApiInstance, f_pAdpcmChanClose, &usAdpcmChanIndex, &usAdpcmMemIndex, &usTsiMemIndex, &usInputTsstIndex, &usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the ADPCM channel. */ + ulResult = Oct6100ApiInvalidateAdpcmChanStructs( f_pApiInstance, usAdpcmMemIndex, usInputTsstIndex, usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the ADPCM channel. */ + ulResult = Oct6100ApiReleaseAdpcmChanResources( f_pApiInstance, usAdpcmChanIndex, usAdpcmMemIndex, usTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Invalidate the handle. */ + f_pAdpcmChanClose->ulChanHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertAdpcmChanParams + +Description: Validate the handle given by the user and verify the state of + the ADPCM channel about to be closed. + Also return all required information to deactivate the channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_pAdpcmChanClose Pointer to ADPCM channel close structure. +f_pusAdpcmChanIndex Index of the ADPCM channel structure in the API list. +f_pusAdpcmMemIndex Index of the ADPCM memory structure in the API list. +f_pusTsiMemIndex Index of the TSI chariot memory used for this channel. +f_pusInputTsstIndex Index of the input entry in the TSST control memory. +f_pusOutputTsstIndex Index of the output entry in the TSST control memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertAdpcmChanParams +UINT32 Oct6100ApiAssertAdpcmChanParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose, + OUT PUINT16 f_pusAdpcmChanIndex, + OUT PUINT16 f_pusAdpcmMemIndex, + OUT PUINT16 f_pusTsiMemIndex, + OUT PUINT16 f_pusInputTsstIndex, + OUT PUINT16 f_pusOutputTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_ADPCM_CHAN pAdpcmChanEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pAdpcmChanClose->ulChanHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_ADPCM_CHANNEL ) + return cOCT6100_ERR_ADPCM_CHAN_INVALID_HANDLE; + + *f_pusAdpcmChanIndex = (UINT16)( f_pAdpcmChanClose->ulChanHndl & cOCT6100_HNDL_INDEX_MASK ); + + if ( *f_pusAdpcmChanIndex >= pSharedInfo->ChipConfig.usMaxAdpcmChannels ) + return cOCT6100_ERR_ADPCM_CHAN_INVALID_HANDLE; + + /*------------------------------------------------------------------------------*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_ADPCM_CHAN_ENTRY_PNT( pSharedInfo, pAdpcmChanEntry, *f_pusAdpcmChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pAdpcmChanClose->ulChanHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pAdpcmChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_ADPCM_CHAN_NOT_OPEN; + if ( ulEntryOpenCnt != pAdpcmChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_ADPCM_CHAN_INVALID_HANDLE; + + /* Return info needed to close the channel and release all resources. */ + *f_pusInputTsstIndex = pAdpcmChanEntry->usInputTsstIndex; + *f_pusOutputTsstIndex = pAdpcmChanEntry->usOutputTsstIndex; + *f_pusTsiMemIndex = pAdpcmChanEntry->usTsiMemIndex; + *f_pusAdpcmMemIndex = pAdpcmChanEntry->usAdpcmMemIndex; + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInvalidateAdpcmChanStructs + +Description: Closes an ADPCM channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usAdpcmMemIndex Index of the ADPCM memory. +f_usInputTsstIndex Index of the input entry in the TSST control memory. +f_usOutputTsstIndex Index of the output entry in the TSST control memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInvalidateAdpcmChanStructs +UINT32 Oct6100ApiInvalidateAdpcmChanStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usAdpcmMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*------------------------------------------------------------------------------*/ + /* Deactivate the TSST control memory. */ + + /* Set the input TSST control entry to unused. */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( f_usInputTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = 0x0000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the output TSST control entry to unused. */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( f_usOutputTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = 0x0000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + + /*------------------------------------------------------------------------------*/ + /* Clear the ADPCM memory. */ + + ulResult = Oct6100ApiClearConversionMemory( f_pApiInstance, f_usAdpcmMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseAdpcmChanResources + +Description: Release and clear the API entry associated to the ADPCM channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_ulAdpcmChanIndex Index of the ADPCM channel in the API list. +f_usAdpcmMemIndex Index of the ADPCM memory used. +f_usTsiMemIndex Index of the TSI memory used. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseAdpcmChanResources +UINT32 Oct6100ApiReleaseAdpcmChanResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usAdpcmChanIndex, + IN UINT16 f_usAdpcmMemIndex, + IN UINT16 f_usTsiMemIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_ADPCM_CHAN pAdpcmChanEntry; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_ADPCM_CHAN_ENTRY_PNT( pSharedInfo, pAdpcmChanEntry, f_usAdpcmChanIndex ); + + /*------------------------------------------------------------------------------*/ + /* Release all resources associated with ADPCM channel. */ + + /* Release the entry in the ADPCM channel list. */ + ulResult = Oct6100ApiReleaseAdpcmChanEntry( f_pApiInstance, f_usAdpcmChanIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, f_usAdpcmMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, f_usTsiMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Release the input TSST entry. */ + ulResult = Oct6100ApiReleaseTsst( + f_pApiInstance, + pAdpcmChanEntry->usInputTimeslot, + pAdpcmChanEntry->usInputStream, + pAdpcmChanEntry->byInputNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Release the output TSST entry. */ + ulResult = Oct6100ApiReleaseTsst( + f_pApiInstance, + pAdpcmChanEntry->usOutputTimeslot, + pAdpcmChanEntry->usOutputStream, + pAdpcmChanEntry->byOutputNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + } + } + } + } + + /* Check if an error occured while releasing the reserved resources. */ + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult >= cOCT6100_ERR_FATAL ) + return ulResult; + else + return cOCT6100_ERR_FATAL_4A; + } + + /*------------------------------------------------------------------------------*/ + + + /*------------------------------------------------------------------------------*/ + /* Update the ADPCM channel's list entry. */ + + /* Mark the channel as closed. */ + pAdpcmChanEntry->fReserved = FALSE; + pAdpcmChanEntry->byEntryOpenCnt++; + + /* Decrement the number of ADPCM channels opened. */ + f_pApiInstance->pSharedInfo->ChipStats.usNumberAdpcmChans--; + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveAdpcmChanEntry + +Description: Reserves one of the ADPCM channel API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pusAdpcmChanIndex Resulting index reserved in the ADPCM channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveAdpcmChanEntry +UINT32 Oct6100ApiReserveAdpcmChanEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusAdpcmChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pAdpcmChanAlloc; + UINT32 ulResult; + UINT32 ulAdpcmChanIndex; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_ADPCM_CHAN_ALLOC_PNT( pSharedInfo, pAdpcmChanAlloc ) + + ulResult = OctapiLlmAllocAlloc( pAdpcmChanAlloc, &ulAdpcmChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_ADPCM_CHAN_ALL_ADPCM_CHAN_ARE_OPENED; + else + return cOCT6100_ERR_FATAL_BE; + } + + *f_pusAdpcmChanIndex = (UINT16)( ulAdpcmChanIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseAdpcmChanEntry + +Description: Releases the specified ADPCM channel API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usAdpcmChanIndex Index reserved in the ADPCM channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseAdpcmChanEntry +UINT32 Oct6100ApiReleaseAdpcmChanEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usAdpcmChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pAdpcmChanAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_ADPCM_CHAN_ALLOC_PNT( pSharedInfo, pAdpcmChanAlloc ) + + ulResult = OctapiLlmAllocDealloc( pAdpcmChanAlloc, f_usAdpcmChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_BF; + } + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_channel.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_channel.c new file mode 100644 index 0000000..2a9f940 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_channel.c @@ -0,0 +1,13858 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_channel.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains functions used to open, modify and close echo + cancellation channels. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 492 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#if defined(__FreeBSD__) +#include +#include +#else +#ifndef __KERNEL__ +#include +#include +#define kmalloc(size, type) malloc(size) +#define kfree(ptr) free(ptr) +#define GFP_ATOMIC 0 /* Dummy */ +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#else +#include +#include +#endif +#endif + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_mixer_inst.h" +#include "oct6100api/oct6100_tsi_cnct_inst.h" +#include "oct6100api/oct6100_conf_bridge_inst.h" +#include "oct6100api/oct6100_tone_detection_inst.h" +#include "oct6100api/oct6100_phasing_tsst_inst.h" +#include "oct6100api/oct6100_tsst_inst.h" +#include "oct6100api/oct6100_channel_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_tsi_cnct_pub.h" +#include "oct6100api/oct6100_playout_buf_pub.h" +#include "oct6100api/oct6100_phasing_tsst_pub.h" +#include "oct6100api/oct6100_mixer_pub.h" +#include "oct6100api/oct6100_conf_bridge_pub.h" +#include "oct6100api/oct6100_tone_detection_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_debug_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_tsst_priv.h" +#include "oct6100_mixer_priv.h" +#include "oct6100_phasing_tsst_priv.h" +#include "oct6100_tsi_cnct_priv.h" +#include "oct6100_playout_buf_priv.h" +#include "oct6100_conf_bridge_priv.h" +#include "oct6100_tone_detection_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_debug_priv.h" + + +/**************************** PUBLIC FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelOpen + +Description: This function opens a echo cancellation channel. An echo cancellation + channel is constituted of two voice stream (RIN/ROUT and SIN/SOUT), and + an echo cancelling core. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelOpen Pointer to echo channel open structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelOpenDef +UINT32 Oct6100ChannelOpenDef( + IN OUT tPOCT6100_CHANNEL_OPEN f_pChannelOpen ) +{ + f_pChannelOpen->pulChannelHndl = NULL; + f_pChannelOpen->ulUserChanId = cOCT6100_INVALID_VALUE; + f_pChannelOpen->ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_POWER_DOWN; + f_pChannelOpen->fEnableToneDisabler = FALSE; + f_pChannelOpen->fEnableExtToneDetection = FALSE; + + /* VQE configuration.*/ + f_pChannelOpen->VqeConfig.fSinDcOffsetRemoval = TRUE; + f_pChannelOpen->VqeConfig.fRinDcOffsetRemoval = TRUE; + f_pChannelOpen->VqeConfig.fRinLevelControl = FALSE; + f_pChannelOpen->VqeConfig.lRinLevelControlGainDb = 0; + f_pChannelOpen->VqeConfig.fSoutLevelControl = FALSE; + f_pChannelOpen->VqeConfig.lSoutLevelControlGainDb = 0; + f_pChannelOpen->VqeConfig.fRinAutomaticLevelControl = FALSE; + f_pChannelOpen->VqeConfig.lRinAutomaticLevelControlTargetDb = -20; + f_pChannelOpen->VqeConfig.fSoutAutomaticLevelControl = FALSE; + f_pChannelOpen->VqeConfig.lSoutAutomaticLevelControlTargetDb = -20; + f_pChannelOpen->VqeConfig.fRinHighLevelCompensation = FALSE; + f_pChannelOpen->VqeConfig.lRinHighLevelCompensationThresholdDb = -10; + f_pChannelOpen->VqeConfig.fSoutAdaptiveNoiseReduction = FALSE; + f_pChannelOpen->VqeConfig.fSoutNoiseBleaching = FALSE; + f_pChannelOpen->VqeConfig.fSoutConferencingNoiseReduction = FALSE; + f_pChannelOpen->VqeConfig.ulComfortNoiseMode = cOCT6100_COMFORT_NOISE_NORMAL; + f_pChannelOpen->VqeConfig.fEnableNlp = TRUE; + f_pChannelOpen->VqeConfig.fEnableTailDisplacement = FALSE; + f_pChannelOpen->VqeConfig.ulTailDisplacement = cOCT6100_AUTO_SELECT_TAIL; + f_pChannelOpen->VqeConfig.ulTailLength = cOCT6100_AUTO_SELECT_TAIL; + + f_pChannelOpen->VqeConfig.fDtmfToneRemoval = FALSE; + + f_pChannelOpen->VqeConfig.fAcousticEcho = FALSE; + f_pChannelOpen->VqeConfig.lDefaultErlDb = -6; + f_pChannelOpen->VqeConfig.ulAecTailLength = 128; + f_pChannelOpen->VqeConfig.lAecDefaultErlDb = 0; + f_pChannelOpen->VqeConfig.ulNonLinearityBehaviorA = 1; + f_pChannelOpen->VqeConfig.ulNonLinearityBehaviorB = 0; + f_pChannelOpen->VqeConfig.ulDoubleTalkBehavior = cOCT6100_DOUBLE_TALK_BEH_NORMAL; + f_pChannelOpen->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb = 0; + f_pChannelOpen->VqeConfig.ulSoutNaturalListenerEnhancementGainDb = 0; + f_pChannelOpen->VqeConfig.fSoutNaturalListenerEnhancement = FALSE; + f_pChannelOpen->VqeConfig.fRoutNoiseReduction = FALSE; + f_pChannelOpen->VqeConfig.lRoutNoiseReductionLevelGainDb = -18; + f_pChannelOpen->VqeConfig.lAnrSnrEnhancementDb = -18; + f_pChannelOpen->VqeConfig.ulAnrVoiceNoiseSegregation = 6; + f_pChannelOpen->VqeConfig.ulToneDisablerVqeActivationDelay = 300; + f_pChannelOpen->VqeConfig.fEnableMusicProtection = FALSE; + /* Older images have idle code detection hard-coded to enabled. */ + f_pChannelOpen->VqeConfig.fIdleCodeDetection = TRUE; + + /* TDM configuration.*/ + f_pChannelOpen->TdmConfig.ulRinNumTssts = 1; + f_pChannelOpen->TdmConfig.ulSinNumTssts = 1; + f_pChannelOpen->TdmConfig.ulRoutNumTssts = 1; + f_pChannelOpen->TdmConfig.ulSoutNumTssts = 1; + + f_pChannelOpen->TdmConfig.ulRinTimeslot = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulRinStream = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulRinPcmLaw = cOCT6100_PCM_U_LAW; + + f_pChannelOpen->TdmConfig.ulSinTimeslot = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulSinStream = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulSinPcmLaw = cOCT6100_PCM_U_LAW; + + f_pChannelOpen->TdmConfig.ulRoutTimeslot = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulRoutStream = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulRoutPcmLaw = cOCT6100_PCM_U_LAW; + + f_pChannelOpen->TdmConfig.ulSoutTimeslot = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulSoutStream = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulSoutPcmLaw = cOCT6100_PCM_U_LAW; + + /* CODEC configuration.*/ + f_pChannelOpen->CodecConfig.ulAdpcmNibblePosition = cOCT6100_ADPCM_IN_LOW_BITS; + + f_pChannelOpen->CodecConfig.ulEncoderPort = cOCT6100_CHANNEL_PORT_SOUT; + f_pChannelOpen->CodecConfig.ulEncodingRate = cOCT6100_G711_64KBPS; + f_pChannelOpen->CodecConfig.ulDecoderPort = cOCT6100_CHANNEL_PORT_RIN; + f_pChannelOpen->CodecConfig.ulDecodingRate = cOCT6100_G711_64KBPS; + + f_pChannelOpen->CodecConfig.fEnableSilenceSuppression = FALSE; + f_pChannelOpen->CodecConfig.ulPhasingTsstHndl = cOCT6100_INVALID_HANDLE; + f_pChannelOpen->CodecConfig.ulPhase = 1; + f_pChannelOpen->CodecConfig.ulPhasingType = cOCT6100_NO_PHASING; + + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelOpen +UINT32 Oct6100ChannelOpen( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_OPEN f_pChannelOpen ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelOpenSer( f_pApiInstance, f_pChannelOpen ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelClose + +Description: This function closes an echo canceller channel + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelClose Pointer to channel close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelCloseDef +UINT32 Oct6100ChannelCloseDef( + IN OUT tPOCT6100_CHANNEL_CLOSE f_pChannelClose ) +{ + f_pChannelClose->ulChannelHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelClose +UINT32 Oct6100ChannelClose( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_CLOSE f_pChannelClose ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelCloseSer( f_pApiInstance, f_pChannelClose ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelModify + +Description: This function will modify the parameter of an echo channel. If + the call to this channel allows the channel to go from power down + to enable, the API will activate it. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelModify Pointer to echo channel change structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelModifyDef +UINT32 Oct6100ChannelModifyDef( + IN OUT tPOCT6100_CHANNEL_MODIFY f_pChannelModify ) +{ + f_pChannelModify->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pChannelModify->ulUserChanId = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->ulEchoOperationMode = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->fEnableToneDisabler = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->fApplyToAllChannels = FALSE; + + f_pChannelModify->fDisableToneDetection = FALSE; + f_pChannelModify->fStopBufferPlayout = FALSE; + f_pChannelModify->fRemoveConfBridgeParticipant = FALSE; + f_pChannelModify->fRemoveBroadcastTssts = FALSE; + + f_pChannelModify->fTdmConfigModified = FALSE; + f_pChannelModify->fVqeConfigModified = FALSE; + f_pChannelModify->fCodecConfigModified = FALSE; + + /* VQE config. */ + f_pChannelModify->VqeConfig.fSinDcOffsetRemoval = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fRinDcOffsetRemoval = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fRinLevelControl = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lRinLevelControlGainDb = (INT32)cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fSoutLevelControl = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lSoutLevelControlGainDb = (INT32)cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fRinAutomaticLevelControl = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lRinAutomaticLevelControlTargetDb = (INT32)cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fSoutAutomaticLevelControl = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lSoutAutomaticLevelControlTargetDb = (INT32)cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fRinHighLevelCompensation = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lRinHighLevelCompensationThresholdDb = (INT32)cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fSoutAdaptiveNoiseReduction = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fSoutNoiseBleaching = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fSoutConferencingNoiseReduction = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulComfortNoiseMode = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fEnableNlp = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fEnableTailDisplacement = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulTailDisplacement = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->VqeConfig.fDtmfToneRemoval = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->VqeConfig.fAcousticEcho = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lDefaultErlDb = (INT32)cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulAecTailLength = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lAecDefaultErlDb = (INT32)cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulNonLinearityBehaviorA = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulNonLinearityBehaviorB = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulDoubleTalkBehavior = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulSoutNaturalListenerEnhancementGainDb = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fSoutNaturalListenerEnhancement = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fRoutNoiseReduction = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lRoutNoiseReductionLevelGainDb = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lAnrSnrEnhancementDb = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulAnrVoiceNoiseSegregation = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulToneDisablerVqeActivationDelay = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fEnableMusicProtection = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fIdleCodeDetection = cOCT6100_KEEP_PREVIOUS_SETTING; + + /* TDM config. */ + f_pChannelModify->TdmConfig.ulRinNumTssts = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulSinNumTssts = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulRoutNumTssts = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulSoutNumTssts = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->TdmConfig.ulRinTimeslot = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulRinStream = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulRinPcmLaw = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->TdmConfig.ulSinTimeslot = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulSinStream = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulSinPcmLaw = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->TdmConfig.ulRoutTimeslot = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulRoutStream = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulRoutPcmLaw = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->TdmConfig.ulSoutTimeslot = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulSoutStream = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulSoutPcmLaw = cOCT6100_KEEP_PREVIOUS_SETTING; + + /* CODEC config. */ + f_pChannelModify->CodecConfig.ulEncoderPort = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->CodecConfig.ulEncodingRate = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->CodecConfig.ulDecoderPort = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->CodecConfig.ulDecodingRate = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->CodecConfig.fEnableSilenceSuppression = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->CodecConfig.ulPhasingTsstHndl = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->CodecConfig.ulPhase = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->CodecConfig.ulPhasingType = cOCT6100_KEEP_PREVIOUS_SETTING; + + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelModify +UINT32 Oct6100ChannelModify( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_MODIFY f_pChannelModify ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Check the apply to all channels flag first. */ + if ( f_pChannelModify->fApplyToAllChannels != TRUE && + f_pChannelModify->fApplyToAllChannels != FALSE ) + return cOCT6100_ERR_CHANNEL_APPLY_TO_ALL_CHANNELS; + + /* Check if must apply modification to all channels. */ + if ( f_pChannelModify->fApplyToAllChannels == TRUE ) + { + tPOCT6100_API_CHANNEL pChanEntry; + UINT16 usChanIndex; + + /* Loop through all channels and look for the opened ones. */ + for ( usChanIndex = 0; usChanIndex < f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels; usChanIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, usChanIndex ); + + /* Check if this one is opened. */ + if ( pChanEntry->fReserved == TRUE ) + { + /* Channel is opened. Form handle and call actual modify function. */ + f_pChannelModify->ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | usChanIndex; + + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelModifySer( f_pApiInstance, f_pChannelModify ); + if ( ulFncRes != cOCT6100_ERR_OK ) + break; + } + } + } + else /* if ( f_pChannelModify->fApplyToAllChannels == FALSE ) */ + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelModifySer( f_pApiInstance, f_pChannelModify ); + } + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelCreateBiDir + +Description: This function creates a bidirectional channel using two standard + echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelCreateBiDir Pointer to channel create BiDir structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelCreateBiDirDef +UINT32 Oct6100ChannelCreateBiDirDef( + IN OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir ) +{ + f_pChannelCreateBiDir->pulBiDirChannelHndl = NULL; + + f_pChannelCreateBiDir->ulFirstChannelHndl = cOCT6100_INVALID_HANDLE; + f_pChannelCreateBiDir->ulSecondChannelHndl = cOCT6100_INVALID_HANDLE; + + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelCreateBiDir +UINT32 Oct6100ChannelCreateBiDir( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelCreateBiDirSer( f_pApiInstance, f_pChannelCreateBiDir ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelDestroyBiDir + +Description: This function destroys a bidirectional channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelDestroyBiDir Pointer to channel destroy BiDir structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelDestroyBiDirDef +UINT32 Oct6100ChannelDestroyBiDirDef( + IN OUT tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir ) +{ + f_pChannelDestroyBiDir->ulBiDirChannelHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelDestroyBiDir +UINT32 Oct6100ChannelDestroyBiDir( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelDestroyBiDirSer( f_pApiInstance, f_pChannelDestroyBiDir ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelBroadcastTsstAdd + +Description: This function adds a TSST to one of the two output ports of a channel. + This TSST can never be modified by a call to Oct6100ChannelModify. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelBroadcastTsstAdd Pointer to the an Add Broadcast TSST structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelBroadcastTsstAddDef +UINT32 Oct6100ChannelBroadcastTsstAddDef( + tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelBroadcastTsstAdd ) +{ + f_pChannelBroadcastTsstAdd->ulChannelHndl = cOCT6100_INVALID_HANDLE; + + f_pChannelBroadcastTsstAdd->ulPort = cOCT6100_INVALID_PORT; + f_pChannelBroadcastTsstAdd->ulTimeslot = cOCT6100_INVALID_TIMESLOT; + f_pChannelBroadcastTsstAdd->ulStream = cOCT6100_INVALID_STREAM; + + return cOCT6100_ERR_OK; + +} +#endif + +#if !SKIP_Oct6100ChannelBroadcastTsstAdd +UINT32 Oct6100ChannelBroadcastTsstAdd( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelBroadcastTsstAdd ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelBroadcastTsstAddSer( f_pApiInstance, f_pChannelBroadcastTsstAdd ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelBroadcastTsstRemove + +Description: This function removes a TSST from one of the two output ports of a channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelBroadcastTsstRemove Pointer to the a Remove Broadcast TSST structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelBroadcastTsstRemoveDef +UINT32 Oct6100ChannelBroadcastTsstRemoveDef( + tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelBroadcastTsstRemove ) +{ + f_pChannelBroadcastTsstRemove->ulChannelHndl = cOCT6100_INVALID_HANDLE; + + f_pChannelBroadcastTsstRemove->ulPort = cOCT6100_INVALID_PORT; + f_pChannelBroadcastTsstRemove->ulTimeslot = cOCT6100_INVALID_TIMESLOT; + f_pChannelBroadcastTsstRemove->ulStream = cOCT6100_INVALID_STREAM; + + f_pChannelBroadcastTsstRemove->fRemoveAll = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ChannelBroadcastTsstRemove +UINT32 Oct6100ChannelBroadcastTsstRemove( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelBroadcastTsstRemove ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelBroadcastTsstRemoveSer( f_pApiInstance, f_pChannelBroadcastTsstRemove ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelGetStats + +Description: This function retrieves all the config and stats related to the channel + designated by ulChannelHndl. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelStats Pointer to a tOCT6100_CHANNEL_STATS structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelGetStatsDef +UINT32 Oct6100ChannelGetStatsDef( + IN OUT tPOCT6100_CHANNEL_STATS f_pChannelStats ) +{ + f_pChannelStats->fResetStats = FALSE; + + f_pChannelStats->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pChannelStats->ulUserChanId = cOCT6100_INVALID_STAT; + f_pChannelStats->ulEchoOperationMode = cOCT6100_INVALID_STAT; + f_pChannelStats->fEnableToneDisabler = FALSE; + f_pChannelStats->ulMutePortsMask = cOCT6100_CHANNEL_MUTE_PORT_NONE; + f_pChannelStats->fEnableExtToneDetection = FALSE; + + /* VQE configuration.*/ + f_pChannelStats->VqeConfig.fEnableNlp = FALSE; + f_pChannelStats->VqeConfig.fEnableTailDisplacement = FALSE; + f_pChannelStats->VqeConfig.ulTailDisplacement = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.ulTailLength = cOCT6100_INVALID_STAT; + + f_pChannelStats->VqeConfig.fSinDcOffsetRemoval = FALSE; + f_pChannelStats->VqeConfig.fRinDcOffsetRemoval = FALSE; + f_pChannelStats->VqeConfig.fRinLevelControl = FALSE; + f_pChannelStats->VqeConfig.fSoutLevelControl = FALSE; + f_pChannelStats->VqeConfig.fRinAutomaticLevelControl = FALSE; + f_pChannelStats->VqeConfig.fSoutAutomaticLevelControl = FALSE; + f_pChannelStats->VqeConfig.fRinHighLevelCompensation = FALSE; + f_pChannelStats->VqeConfig.fAcousticEcho = FALSE; + f_pChannelStats->VqeConfig.fSoutAdaptiveNoiseReduction = FALSE; + f_pChannelStats->VqeConfig.fDtmfToneRemoval = FALSE; + + f_pChannelStats->VqeConfig.fSoutNoiseBleaching = FALSE; + f_pChannelStats->VqeConfig.fSoutConferencingNoiseReduction = FALSE; + + f_pChannelStats->VqeConfig.ulComfortNoiseMode = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.ulNonLinearityBehaviorA = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.ulNonLinearityBehaviorB = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.ulDoubleTalkBehavior = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.lRinLevelControlGainDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.lSoutLevelControlGainDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.lRinAutomaticLevelControlTargetDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.lSoutAutomaticLevelControlTargetDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.lRinHighLevelCompensationThresholdDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.lDefaultErlDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.lAecDefaultErlDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.ulAecTailLength = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.ulSoutNaturalListenerEnhancementGainDb = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.fSoutNaturalListenerEnhancement = FALSE; + f_pChannelStats->VqeConfig.fRoutNoiseReduction = FALSE; + f_pChannelStats->VqeConfig.lRoutNoiseReductionLevelGainDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.lAnrSnrEnhancementDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.ulAnrVoiceNoiseSegregation = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.ulToneDisablerVqeActivationDelay = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.fEnableMusicProtection = FALSE; + f_pChannelStats->VqeConfig.fIdleCodeDetection = FALSE; + + + + /* TDM configuration.*/ + f_pChannelStats->TdmConfig.ulMaxBroadcastTssts = 0; + f_pChannelStats->TdmConfig.fMoreRoutBroadcastTssts = FALSE; + f_pChannelStats->TdmConfig.fMoreSoutBroadcastTssts = FALSE; + + f_pChannelStats->TdmConfig.ulNumRoutBroadcastTssts = 0; + f_pChannelStats->TdmConfig.ulNumSoutBroadcastTssts = 0; + + f_pChannelStats->TdmConfig.ulRinNumTssts = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulSinNumTssts = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulRoutNumTssts = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulSoutNumTssts = cOCT6100_INVALID_STAT; + + f_pChannelStats->TdmConfig.ulRinTimeslot = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulRinStream = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulRinPcmLaw = cOCT6100_INVALID_STAT; + + f_pChannelStats->TdmConfig.ulSinTimeslot = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulSinStream = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulSinPcmLaw = cOCT6100_INVALID_STAT; + + f_pChannelStats->TdmConfig.ulRoutTimeslot = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulRoutStream = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulRoutPcmLaw = cOCT6100_INVALID_STAT; + + f_pChannelStats->TdmConfig.pulRoutBroadcastTimeslot = NULL; + f_pChannelStats->TdmConfig.pulRoutBroadcastStream = NULL; + + f_pChannelStats->TdmConfig.ulSoutTimeslot = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulSoutStream = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulSoutPcmLaw = cOCT6100_INVALID_STAT; + + f_pChannelStats->TdmConfig.pulSoutBroadcastTimeslot = NULL; + f_pChannelStats->TdmConfig.pulSoutBroadcastStream = NULL; + + + /* CODEC configuration.*/ + f_pChannelStats->CodecConfig.ulAdpcmNibblePosition = cOCT6100_INVALID_STAT; + + f_pChannelStats->CodecConfig.ulEncoderPort = cOCT6100_INVALID_STAT; + f_pChannelStats->CodecConfig.ulEncodingRate = cOCT6100_INVALID_STAT; + f_pChannelStats->CodecConfig.ulDecoderPort = cOCT6100_INVALID_STAT; + f_pChannelStats->CodecConfig.ulDecodingRate = cOCT6100_INVALID_STAT; + + f_pChannelStats->CodecConfig.fEnableSilenceSuppression = FALSE; + f_pChannelStats->CodecConfig.ulPhasingTsstHndl = cOCT6100_INVALID_STAT; + f_pChannelStats->CodecConfig.ulPhase = cOCT6100_INVALID_STAT; + f_pChannelStats->CodecConfig.ulPhasingType = cOCT6100_INVALID_STAT; + + f_pChannelStats->ulNumEchoPathChanges = cOCT6100_INVALID_STAT; + f_pChannelStats->ulToneDisablerStatus = cOCT6100_INVALID_STAT; + f_pChannelStats->fEchoCancellerConverged = FALSE; + f_pChannelStats->fSinVoiceDetected = FALSE; + f_pChannelStats->lCurrentERL = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->lCurrentERLE = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->ulCurrentEchoDelay = cOCT6100_INVALID_STAT; + + f_pChannelStats->lMaxERL = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->lMaxERLE = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->ulMaxEchoDelay = cOCT6100_INVALID_STAT; + + f_pChannelStats->lRinLevel = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->lSinLevel = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->lRinAppliedGain = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->lSoutAppliedGain = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->lComfortNoiseLevel = cOCT6100_INVALID_SIGNED_STAT; + + + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelGetStats +UINT32 Oct6100ChannelGetStats( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_STATS f_pChannelStats ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ApiChannelGetStatsSer( f_pApiInstance, f_pChannelStats ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelMute + +Description: This function mutes some or all of the ports designated by + ulChannelHndl. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelMute Pointer to a tPOCT6100_CHANNEL_MUTE structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelMuteDef +UINT32 Oct6100ChannelMuteDef( + IN OUT tPOCT6100_CHANNEL_MUTE f_pChannelMute ) +{ + f_pChannelMute->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pChannelMute->ulPortMask = cOCT6100_CHANNEL_MUTE_PORT_NONE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelMute +UINT32 Oct6100ChannelMute( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_MUTE f_pChannelMute ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelMuteSer( f_pApiInstance, f_pChannelMute ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelUnMute + +Description: This function unmutes some or all of the ports designated by + ulChannelHndl. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelUnMute Pointer to a tPOCT6100_CHANNEL_UNMUTE structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelUnMuteDef +UINT32 Oct6100ChannelUnMuteDef( + IN OUT tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute ) +{ + f_pChannelUnMute->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pChannelUnMute->ulPortMask = cOCT6100_CHANNEL_MUTE_PORT_NONE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelUnMute +UINT32 Oct6100ChannelUnMute( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelUnMuteSer( f_pApiInstance, f_pChannelUnMute ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + +/**************************** PRIVATE FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetChannelsEchoSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of the ECHO memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pOpenChip Pointer to chip configuration struct. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetChannelsEchoSwSizes +UINT32 Oct6100ApiGetChannelsEchoSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + UINT32 ulMaxChannels; + + ulMaxChannels = f_pOpenChip->ulMaxChannels; + + if ( f_pOpenChip->fEnableChannelRecording == TRUE && ulMaxChannels != 672 ) + ulMaxChannels++; + + /* Determine the amount of memory required for the API echo channel list.*/ + f_pInstSizes->ulChannelList = ulMaxChannels * sizeof( tOCT6100_API_CHANNEL ); /* Add one for the record channel.*/ + f_pInstSizes->ulBiDirChannelList = f_pOpenChip->ulMaxBiDirChannels * sizeof( tOCT6100_API_BIDIR_CHANNEL ); + if ( ulMaxChannels > 0 ) + { + /* Calculate memory needed for ECHO memory allocation */ + ulResult = OctapiLlmAllocGetSize( ulMaxChannels, &f_pInstSizes->ulChannelAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_0; + } + else + { + f_pInstSizes->ulChannelAlloc = 0; + } + if ( f_pOpenChip->ulMaxBiDirChannels > 0 ) + { + /* Calculate memory needed for ECHO memory allocation */ + ulResult = OctapiLlmAllocGetSize( f_pOpenChip->ulMaxBiDirChannels, &f_pInstSizes->ulBiDirChannelAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_0; + } + else + { + f_pInstSizes->ulBiDirChannelAlloc = 0; + } + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulChannelList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulChannelAlloc, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulBiDirChannelList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulBiDirChannelAlloc, ulTempVar ) + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiChannelsEchoSwInit + +Description: Initializes all elements of the instance structure associated + to the ECHO memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiChannelsEchoSwInit +UINT32 Oct6100ApiChannelsEchoSwInit( + IN tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_API_CHANNEL pChannelsEchoList; + tPOCT6100_API_BIDIR_CHANNEL pBiDirChannelsList; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT16 usMaxChannels; + PVOID pEchoChanAlloc; + PVOID pBiDirChanAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of the API instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Initialize the ECHO channel API list.*/ + usMaxChannels = pSharedInfo->ChipConfig.usMaxChannels; + + /* add a channel to initialize if the recording is activated. */ + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + usMaxChannels++; + + /* Set all entries in the ADCPM channel list to unused. */ + mOCT6100_GET_CHANNEL_LIST_PNT( pSharedInfo, pChannelsEchoList ); + + /* Initialize the API ECHO channels allocation software to "all free". */ + if ( usMaxChannels > 0 ) + { + /* Clear the memory */ + Oct6100UserMemSet( pChannelsEchoList, 0x00, sizeof(tOCT6100_API_CHANNEL) * usMaxChannels ); + + mOCT6100_GET_CHANNEL_ALLOC_PNT( pSharedInfo, pEchoChanAlloc ) + + ulResult = OctapiLlmAllocInit( &pEchoChanAlloc, usMaxChannels ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1; + } + + mOCT6100_GET_BIDIR_CHANNEL_LIST_PNT( pSharedInfo, pBiDirChannelsList ); + + if ( pSharedInfo->ChipConfig.usMaxBiDirChannels > 0 ) + { + /* Clear the memory */ + Oct6100UserMemSet( pBiDirChannelsList, 0x00, sizeof(tOCT6100_API_BIDIR_CHANNEL) * pSharedInfo->ChipConfig.usMaxBiDirChannels ); + + mOCT6100_GET_BIDIR_CHANNEL_ALLOC_PNT( pSharedInfo, pBiDirChanAlloc ) + + ulResult = OctapiLlmAllocInit( &pBiDirChanAlloc, pSharedInfo->ChipConfig.usMaxBiDirChannels ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A9; + + } + + return cOCT6100_ERR_OK; +} +#endif + + + + + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelOpenSer + +Description: Opens a echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelOpen Pointer to channel configuration structure. Then handle + identifying the buffer in all future function calls is + returned in this structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelOpenSer +UINT32 Oct6100ChannelOpenSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_OPEN f_pChannelOpen ) +{ + tOCT6100_API_ECHO_CHAN_INDEX *ChannelIndexConf; + UINT32 ulResult; + + ChannelIndexConf = kmalloc(sizeof(*ChannelIndexConf), GFP_ATOMIC); + + if (!ChannelIndexConf) + return cOCT6100_ERR_FATAL_0; + + /* Check the user's configuration of the echo cancellation channel for errors. */ + ulResult = Oct6100ApiCheckChannelParams( f_pApiInstance, f_pChannelOpen, ChannelIndexConf ); + if ( ulResult != cOCT6100_ERR_OK ) + goto out; + + /* Reserve all resources needed by the echo cancellation channel. */ + ulResult = Oct6100ApiReserveChannelResources( f_pApiInstance, f_pChannelOpen, ChannelIndexConf ); + if ( ulResult != cOCT6100_ERR_OK ) + goto out; + + /* Write all necessary structures to activate the echo cancellation channel. */ + ulResult = Oct6100ApiWriteChannelStructs( f_pApiInstance, f_pChannelOpen, ChannelIndexConf ); + if ( ulResult != cOCT6100_ERR_OK ) + goto out; + + /* Update the new echo cancellation channels's entry in the ECHO channel list. */ + ulResult = Oct6100ApiUpdateChannelEntry( f_pApiInstance, f_pChannelOpen, ChannelIndexConf ); + if ( ulResult != cOCT6100_ERR_OK ) + goto out; + + kfree(ChannelIndexConf); + return cOCT6100_ERR_OK; + +out: + kfree(ChannelIndexConf); + return ulResult; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckChannelParams + +Description: Checks the user's echo cancellation channel open configuration for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelOpen Pointer to echo cancellation channel open configuration structure. +f_pChanIndexConf Pointer to a structure used to store the multiple resources indexes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckChannelParams +UINT32 Oct6100ApiCheckChannelParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + OUT tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf ) +{ + tPOCT6100_CHANNEL_OPEN_TDM pTdmConfig; + tPOCT6100_CHANNEL_OPEN_VQE pVqeConfig; + tPOCT6100_CHANNEL_OPEN_CODEC pCodecConfig; + UINT32 ulDecoderNumTssts; + UINT32 ulResult; + + /* Dereference the configuration structure for clearer code and faster access.*/ + pTdmConfig = &f_pChannelOpen->TdmConfig; + pVqeConfig = &f_pChannelOpen->VqeConfig; + pCodecConfig = &f_pChannelOpen->CodecConfig; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels == 0 ) + return cOCT6100_ERR_CHANNEL_DISABLED; + + if ( f_pChannelOpen->pulChannelHndl == NULL ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + if ( f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_NORMAL && + f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_HT_FREEZE && + f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_HT_RESET && + f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_POWER_DOWN && + f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_EXTERNAL && + f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION && + f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_NO_ECHO ) + return cOCT6100_ERR_CHANNEL_ECHO_OP_MODE; + + /* Check the 2100Hz echo disabling configuration.*/ + if ( f_pChannelOpen->fEnableToneDisabler != TRUE && + f_pChannelOpen->fEnableToneDisabler != FALSE ) + return cOCT6100_ERR_CHANNEL_TONE_DISABLER_ENABLE; + + /* Check the extended Tone Detection flag value.*/ + if ( f_pChannelOpen->fEnableExtToneDetection != TRUE && + f_pChannelOpen->fEnableExtToneDetection != FALSE ) + return cOCT6100_ERR_CHANNEL_ENABLE_EXT_TONE_DETECTION; + + /* Check that extented tone detection is actually enabled by the user. */ + if ( ( f_pChannelOpen->fEnableExtToneDetection == TRUE ) && + ( f_pApiInstance->pSharedInfo->ChipConfig.fEnableExtToneDetection == FALSE ) ) + return cOCT6100_ERR_CHANNEL_EXT_TONE_DETECTION_DISABLED; + + + + /*==============================================================================*/ + /* Check the TDM configuration parameters.*/ + + ulResult = Oct6100ApiCheckTdmConfig( f_pApiInstance, pTdmConfig ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Now validate the VQE parameters */ + + ulResult = Oct6100ApiCheckVqeConfig( f_pApiInstance, pVqeConfig, f_pChannelOpen->fEnableToneDisabler ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Verify if the echo operation mode selected can be applied. */ + if ( ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_NO_ECHO ) + && ( pVqeConfig->fEnableNlp == FALSE ) ) + return cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_NLP_REQUIRED; + + if ( ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) + && ( pVqeConfig->fEnableNlp == FALSE ) ) + return cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_NLP_REQUIRED; + + /* Comfort noise must be activated for speech recognition mode to work. */ + if ( ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) + && ( pVqeConfig->ulComfortNoiseMode == cOCT6100_COMFORT_NOISE_OFF ) ) + return cOCT6100_ERR_CHANNEL_COMFORT_NOISE_REQUIRED; + + /*==============================================================================*/ + + /*==============================================================================*/ + /* Finally, validate the CODEC configuration.*/ + + if ( pCodecConfig->ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + ulDecoderNumTssts = pTdmConfig->ulRinNumTssts; + else /* pCodecConfig->ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN */ + ulDecoderNumTssts = pTdmConfig->ulSinNumTssts; + + ulResult = Oct6100ApiCheckCodecConfig( f_pApiInstance, pCodecConfig, ulDecoderNumTssts, &f_pChanIndexConf->usPhasingTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + + /* make sure that if silence suppression is activated, the NLP is enabled.*/ + if ( pCodecConfig->fEnableSilenceSuppression == TRUE && pVqeConfig->fEnableNlp == FALSE ) + return cOCT6100_ERR_CHANNEL_SIL_SUP_NLP_MUST_BE_ENABLED; + + /* Verify if law conversion is allowed. */ + if ( pCodecConfig->ulEncoderPort == cOCT6100_NO_ENCODING || + pCodecConfig->ulDecoderPort == cOCT6100_NO_DECODING ) + { + /* No law conversion can occurs if one ADPCM memory is not reserved.*/ + if ( pTdmConfig->ulRinPcmLaw != pTdmConfig->ulRoutPcmLaw ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_LAW_TRANSLATION; + + if ( pTdmConfig->ulSinPcmLaw != pTdmConfig->ulSoutPcmLaw ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_LAW_TRANSLATION; + } + + /* Verify if the config supports extended tone detection.*/ + if ( f_pChannelOpen->fEnableExtToneDetection == TRUE ) + { + if ( pCodecConfig->ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + return cOCT6100_ERR_CHANNEL_EXT_TONE_DETECTION_DECODER_PORT; + } + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveChannelResources + +Description: Reserves all resources needed for the new channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelOpen Pointer to echo cancellation channel configuration structure. +f_pulChannelIndex Allocated entry in ECHO channel list. +f_pChanIndexConf Pointer to a structure used to store the multiple resources indexes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveChannelResources +UINT32 Oct6100ApiReserveChannelResources( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + OUT tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf ) +{ + tPOCT6100_CHANNEL_OPEN_TDM pTdmConfig; + tPOCT6100_CHANNEL_OPEN_CODEC pCodecConfig; + + UINT32 ulResult; + UINT32 ulTempVar; + UINT32 ulFreeMixerEventCnt; + + BOOL fRinTsstEntry = FALSE; + BOOL fSinTsstEntry = FALSE; + BOOL fRoutTsstEntry = FALSE; + BOOL fSoutTsstEntry = FALSE; + + BOOL fRinRoutTsiMemEntry = FALSE; + BOOL fSinSoutTsiMemEntry = FALSE; + + BOOL fEchoChanEntry = FALSE; + + PUINT16 pusRinRoutConversionMemIndex = NULL; + PUINT16 pusSinSoutConversionMemIndex = NULL; + BOOL fRinRoutConversionMemEntry = FALSE; + BOOL fSinSoutConversionMemEntry = FALSE; + + BOOL fExtToneChanEntry = FALSE; + BOOL fExtToneTsiEntry = FALSE; + BOOL fExtToneMixerEntry = FALSE; + + /* Obtain a local pointer to the configuration structures.*/ + pTdmConfig = &f_pChannelOpen->TdmConfig; + pCodecConfig = &f_pChannelOpen->CodecConfig; + + /*===============================================================================*/ + /* Reserve Echo and TSI entries. */ + + ulResult = Oct6100ApiReserveEchoEntry( f_pApiInstance, + &f_pChanIndexConf->usEchoChanIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fEchoChanEntry = TRUE; + + /* Set the echo, encoder and decoder memory indexes.*/ + f_pChanIndexConf->usEchoMemIndex = f_pChanIndexConf->usEchoChanIndex; + + /* Reserve an entry for the RIN/ROUT tsi chariot memory. */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, + &f_pChanIndexConf->usRinRoutTsiMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fRinRoutTsiMemEntry = TRUE; + + /* Reserve an entry for the SIN/SOUT tsi chariot memory. */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, + &f_pChanIndexConf->usSinSoutTsiMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fSinSoutTsiMemEntry = TRUE; + + /* Reserve an ADPCM memory block for compression if required.*/ + if ( pCodecConfig->ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + pusRinRoutConversionMemIndex = &f_pChanIndexConf->usRinRoutConversionMemIndex; + } + else if ( pCodecConfig->ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + pusSinSoutConversionMemIndex = &f_pChanIndexConf->usSinSoutConversionMemIndex; + } + + /* Reserve an ADPCM memory block for decompression if required.*/ + if ( pCodecConfig->ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + pusRinRoutConversionMemIndex = &f_pChanIndexConf->usRinRoutConversionMemIndex; + } + else if ( pCodecConfig->ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN ) + { + pusSinSoutConversionMemIndex = &f_pChanIndexConf->usSinSoutConversionMemIndex; + } + + + /* Reserve the conversion memories. */ + if ( pusRinRoutConversionMemIndex != NULL ) + { + /* Reserve a conversion memory for the Rin/Rout stream. */ + ulResult = Oct6100ApiReserveConversionMemEntry( f_pApiInstance, + pusRinRoutConversionMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fRinRoutConversionMemEntry = TRUE; + } + } + else + { + /* No conversion memory reserved.*/ + f_pChanIndexConf->usRinRoutConversionMemIndex = cOCT6100_INVALID_INDEX; + } + + if ( ( pusSinSoutConversionMemIndex != NULL ) && + ( ulResult == cOCT6100_ERR_OK ) ) + { + /* Reserve a conversion memory for the Sin/Sout stream. */ + ulResult = Oct6100ApiReserveConversionMemEntry( f_pApiInstance, + pusSinSoutConversionMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fSinSoutConversionMemEntry = TRUE; + } + } + else + { + /* No conversion memory reserved.*/ + f_pChanIndexConf->usSinSoutConversionMemIndex = cOCT6100_INVALID_INDEX; + } + + /* Reserve any resources required if the extended Tone detection is enabled.*/ + if ( f_pChannelOpen->fEnableExtToneDetection == TRUE ) + { + ulResult = Oct6100ApiReserveEchoEntry( f_pApiInstance, + &f_pChanIndexConf->usExtToneChanIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fExtToneChanEntry = TRUE; + + /* Reserve an entry for the TSI chariot memory for the additionnal channel. */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, + &f_pChanIndexConf->usExtToneTsiIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fExtToneTsiEntry = TRUE; + + /* Reserve an entry for the TSI chariot memory for the additionnal channel. */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, + &f_pChanIndexConf->usExtToneMixerIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + fExtToneMixerEntry = TRUE; + } + } + } + else + { + f_pChanIndexConf->usExtToneChanIndex = cOCT6100_INVALID_INDEX; + f_pChanIndexConf->usExtToneMixerIndex = cOCT6100_INVALID_INDEX; + f_pChanIndexConf->usExtToneTsiIndex = cOCT6100_INVALID_INDEX; + } + } + else + { + /* Return an error other then a Fatal.*/ + ulResult = cOCT6100_ERR_CHANNEL_OUT_OF_TSI_MEMORY; + } + } + else + { + /* Return an error other then a Fatal.*/ + ulResult = cOCT6100_ERR_CHANNEL_OUT_OF_TSI_MEMORY; + } + } + + /*===============================================================================*/ + + /*===============================================================================*/ + /* Now reserve the TSST entries if required.*/ + + /* Reserve the Rin TSST entry */ + if ( (ulResult == cOCT6100_ERR_OK ) && + (pTdmConfig->ulRinTimeslot != cOCT6100_UNASSIGNED && + pTdmConfig->ulRinStream != cOCT6100_UNASSIGNED) ) + { + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pTdmConfig->ulRinTimeslot, + pTdmConfig->ulRinStream, + pTdmConfig->ulRinNumTssts, + cOCT6100_INPUT_TSST, + &f_pChanIndexConf->usRinTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + fRinTsstEntry = TRUE; + } + else + { + f_pChanIndexConf->usRinTsstIndex = cOCT6100_INVALID_INDEX; + } + + + if ( (ulResult == cOCT6100_ERR_OK ) && + (pTdmConfig->ulSinTimeslot != cOCT6100_UNASSIGNED && + pTdmConfig->ulSinStream != cOCT6100_UNASSIGNED) ) + { + /* Reserve the Sin TSST entry.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pTdmConfig->ulSinTimeslot, + pTdmConfig->ulSinStream, + pTdmConfig->ulSinNumTssts, + cOCT6100_INPUT_TSST, + &f_pChanIndexConf->usSinTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + fSinTsstEntry = TRUE; + } + else + { + f_pChanIndexConf->usSinTsstIndex = cOCT6100_INVALID_INDEX; + } + + if ( (ulResult == cOCT6100_ERR_OK ) && + (pTdmConfig->ulRoutTimeslot != cOCT6100_UNASSIGNED && + pTdmConfig->ulRoutStream != cOCT6100_UNASSIGNED) ) + { + /* Reserve the Rout TSST entry.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pTdmConfig->ulRoutTimeslot, + pTdmConfig->ulRoutStream, + pTdmConfig->ulRoutNumTssts, + cOCT6100_OUTPUT_TSST, + &f_pChanIndexConf->usRoutTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + fRoutTsstEntry = TRUE; + } + else + { + f_pChanIndexConf->usRoutTsstIndex = cOCT6100_INVALID_INDEX; + } + + + if ( (ulResult == cOCT6100_ERR_OK ) && + (pTdmConfig->ulSoutTimeslot != cOCT6100_UNASSIGNED && + pTdmConfig->ulSoutStream != cOCT6100_UNASSIGNED) ) + { + /* Reserve the Sout TSST entry.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pTdmConfig->ulSoutTimeslot, + pTdmConfig->ulSoutStream, + pTdmConfig->ulSoutNumTssts, + cOCT6100_OUTPUT_TSST, + &f_pChanIndexConf->usSoutTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + fSoutTsstEntry = TRUE; + } + else + { + f_pChanIndexConf->usSoutTsstIndex = cOCT6100_INVALID_INDEX; + } + + /*===============================================================================*/ + + + /*===============================================================================*/ + /* Check if there are a couple of mixer events available for us. */ + + if ( ulResult == cOCT6100_ERR_OK ) + { + UINT32 ulMixerEventCntNeeded = 0; + + /* Calculate how many mixer events are needed. */ + if ( f_pChanIndexConf->usRinTsstIndex == cOCT6100_INVALID_INDEX ) + ulMixerEventCntNeeded++; + + if ( f_pChanIndexConf->usSinTsstIndex == cOCT6100_INVALID_INDEX ) + ulMixerEventCntNeeded++; + + /* If at least 1 mixer event is needed, check if those are available. */ + if ( ulMixerEventCntNeeded != 0 ) + { + ulResult = Oct6100ApiGetFreeMixerEventCnt( f_pApiInstance, &ulFreeMixerEventCnt ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* The API might need more mixer events if the ports have to be muted. */ + /* Check if these are available. */ + if ( ulFreeMixerEventCnt < ulMixerEventCntNeeded ) + { + ulResult = cOCT6100_ERR_CHANNEL_OUT_OF_MIXER_EVENTS; + } + } + } + } + + /*===============================================================================*/ + + + /*===============================================================================*/ + /* Release the resources if something went wrong */ + if ( ulResult != cOCT6100_ERR_OK ) + { + /*===============================================================================*/ + /* Release the previously reserved resources .*/ + if( fRinTsstEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->ulRinTimeslot, + pTdmConfig->ulRinStream, + pTdmConfig->ulRinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fSinTsstEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->ulSinTimeslot, + pTdmConfig->ulSinStream, + pTdmConfig->ulSinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fRoutTsstEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->ulRoutTimeslot, + pTdmConfig->ulRoutStream, + pTdmConfig->ulRoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fSoutTsstEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->ulSoutTimeslot, + pTdmConfig->ulSoutStream, + pTdmConfig->ulSoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fRinRoutTsiMemEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, + f_pChanIndexConf->usRinRoutTsiMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fSinSoutTsiMemEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, + f_pChanIndexConf->usSinSoutTsiMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /*===============================================================================*/ + + /*===============================================================================*/ + /* Release the previously reserved echo resources .*/ + if( fEchoChanEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseEchoEntry( f_pApiInstance, + f_pChanIndexConf->usEchoChanIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /*===============================================================================*/ + + /*===============================================================================*/ + /* Release the previously reserved resources for the extended tone detection.*/ + if( fExtToneChanEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseEchoEntry( f_pApiInstance, + f_pChanIndexConf->usExtToneChanIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fExtToneTsiEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, + f_pChanIndexConf->usExtToneTsiIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fExtToneMixerEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, + f_pChanIndexConf->usExtToneMixerIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + /*===============================================================================*/ + + /*===============================================================================*/ + /* Release the conversion resources. */ + if( fRinRoutConversionMemEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, + f_pChanIndexConf->usRinRoutConversionMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fSinSoutConversionMemEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, + f_pChanIndexConf->usSinSoutConversionMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /*===============================================================================*/ + + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteChannelStructs + +Description: Performs all the required structure writes to configure the + new echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelOpen Pointer to echo cancellation channel configuration structure. +f_pChanIndexConf Pointer to a structure used to store the multiple resources indexes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteChannelStructs +UINT32 Oct6100ApiWriteChannelStructs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + OUT tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_CHANNEL_OPEN_TDM pTdmConfig; + tOCT6100_WRITE_PARAMS WriteParams; + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulResult; + UINT32 ulDwordAddress; + UINT32 ulDwordData; + BOOL fProgramAdpcmMem; + UINT32 ulCompType = 0; + UINT32 ulPcmLaw; + UINT16 usTempTsiMemIndex; + UINT16 usConversionMemIndex; + UINT32 ulToneEventNumber; + BOOL fSSTone; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a local pointer to the TDM configuration structure.*/ + pTdmConfig = &f_pChannelOpen->TdmConfig; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, f_pChanIndexConf->usEchoChanIndex ); + + /*==============================================================================*/ + /* Configure the Input Tsst control memory.*/ + + /* Set the RIN Tsst control entry.*/ + if ( f_pChanIndexConf->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_pChanIndexConf->usRinTsstIndex, + f_pChanIndexConf->usRinRoutTsiMemIndex, + pTdmConfig->ulRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Set the SIN Tsst control entry.*/ + if ( f_pChanIndexConf->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_pChanIndexConf->usSinTsstIndex, + f_pChanIndexConf->usSinSoutTsiMemIndex, + pTdmConfig->ulSinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*==============================================================================*/ + + /*==============================================================================*/ + /* Configure the ADPCM control memory for the Decoder.*/ + + /* Set the codec state flags.*/ + f_pChanIndexConf->fRinRoutCodecActive = FALSE; + f_pChanIndexConf->fSinSoutCodecActive = FALSE; + + if ( f_pChannelOpen->CodecConfig.ulDecoderPort != cOCT6100_NO_DECODING ) + { + fProgramAdpcmMem = TRUE; + + switch( f_pChannelOpen->CodecConfig.ulDecodingRate ) + { + case cOCT6100_G711_64KBPS: + ulCompType = 0x8; + if ( f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + if ( pTdmConfig->ulRinPcmLaw == pTdmConfig->ulRoutPcmLaw ) + fProgramAdpcmMem = FALSE; + + /* Check if both ports are assigned. If not, no law conversion needed here.. */ + if ( ( pTdmConfig->ulRinStream == cOCT6100_UNASSIGNED ) + || ( pTdmConfig->ulRoutStream == cOCT6100_UNASSIGNED ) ) + fProgramAdpcmMem = FALSE; + } + else /* f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN */ + { + if ( pTdmConfig->ulSinPcmLaw == pTdmConfig->ulSoutPcmLaw ) + fProgramAdpcmMem = FALSE; + + if ( ( pTdmConfig->ulSinStream == cOCT6100_UNASSIGNED ) + || ( pTdmConfig->ulSoutStream == cOCT6100_UNASSIGNED ) ) + fProgramAdpcmMem = FALSE; + } + break; + case cOCT6100_G726_40KBPS: + ulCompType = 0x3; + break; + + case cOCT6100_G726_32KBPS: + ulCompType = 0x2; + break; + + case cOCT6100_G726_24KBPS: + ulCompType = 0x1; + break; + + case cOCT6100_G726_16KBPS: + ulCompType = 0x0; + break; + + case cOCT6100_G727_2C_ENCODED: + ulCompType = 0x4; + break; + + case cOCT6100_G727_3C_ENCODED: + ulCompType = 0x5; + break; + + case cOCT6100_G727_4C_ENCODED: + ulCompType = 0x6; + break; + + case cOCT6100_G726_ENCODED: + ulCompType = 0x9; + break; + + case cOCT6100_G711_G726_ENCODED: + ulCompType = 0xA; + break; + + case cOCT6100_G711_G727_2C_ENCODED: + ulCompType = 0xC; + break; + + case cOCT6100_G711_G727_3C_ENCODED: + ulCompType = 0xD; + break; + + case cOCT6100_G711_G727_4C_ENCODED: + ulCompType = 0xE; + break; + default: + return cOCT6100_ERR_FATAL_D4; + } + + if ( fProgramAdpcmMem == TRUE ) + { + /* Set the chariot memory based on the selected port.*/ + if ( f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + usTempTsiMemIndex = f_pChanIndexConf->usRinRoutTsiMemIndex; + ulPcmLaw = pTdmConfig->ulRoutPcmLaw; /* Set the law for later use */ + + /* Set the codec state flags.*/ + f_pChanIndexConf->fRinRoutCodecActive = TRUE; + + /* Set the conversion memory index to use for decompression */ + usConversionMemIndex = f_pChanIndexConf->usRinRoutConversionMemIndex; + } + else /* f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN */ + { + usTempTsiMemIndex = f_pChanIndexConf->usSinSoutTsiMemIndex; + ulPcmLaw = pTdmConfig->ulSoutPcmLaw; /* Set the law for later use */ + + /* Set the codec state flags.*/ + f_pChanIndexConf->fSinSoutCodecActive = TRUE; + + /* Set the conversion memory index to use for decompression */ + usConversionMemIndex = f_pChanIndexConf->usSinSoutConversionMemIndex; + } + + ulResult = Oct6100ApiWriteDecoderMemory( f_pApiInstance, + usConversionMemIndex, + ulCompType, + usTempTsiMemIndex, + ulPcmLaw, + f_pChannelOpen->CodecConfig.ulAdpcmNibblePosition ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Configure the ADPCM control memory for the Encoder */ + + if ( f_pChannelOpen->CodecConfig.ulEncoderPort != cOCT6100_NO_ENCODING ) + { + fProgramAdpcmMem = TRUE; + + switch( f_pChannelOpen->CodecConfig.ulEncodingRate ) + { + case cOCT6100_G711_64KBPS: + if ( f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + if ( pTdmConfig->ulRoutPcmLaw == cOCT6100_PCM_U_LAW ) + ulCompType = 0x4; + else + ulCompType = 0x5; + + /* Check for law conversion.*/ + if ( pTdmConfig->ulRinPcmLaw == pTdmConfig->ulRoutPcmLaw ) + fProgramAdpcmMem = FALSE; + + /* Check if both ports are assigned. If not, no law conversion needed here.. */ + if ( ( pTdmConfig->ulRinStream == cOCT6100_UNASSIGNED ) + || ( pTdmConfig->ulRoutStream == cOCT6100_UNASSIGNED ) ) + fProgramAdpcmMem = FALSE; + } + else /* f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + if ( pTdmConfig->ulSoutPcmLaw == cOCT6100_PCM_U_LAW ) + ulCompType = 0x4; + else + ulCompType = 0x5; + + /* Check for law conversion.*/ + if ( pTdmConfig->ulSinPcmLaw == pTdmConfig->ulSoutPcmLaw ) + fProgramAdpcmMem = FALSE; + + /* Check if both ports are assigned. If not, no law conversion needed here.. */ + if ( ( pTdmConfig->ulSinStream == cOCT6100_UNASSIGNED ) + || ( pTdmConfig->ulSoutStream == cOCT6100_UNASSIGNED ) ) + fProgramAdpcmMem = FALSE; + } + + break; + case cOCT6100_G726_40KBPS: + ulCompType = 0x3; + break; + + case cOCT6100_G726_32KBPS: + ulCompType = 0x2; + break; + + case cOCT6100_G726_24KBPS: + ulCompType = 0x1; + break; + + case cOCT6100_G726_16KBPS: + ulCompType = 0x0; + break; + + case cOCT6100_G727_40KBPS_4_1: + ulCompType = 0xD; + break; + + case cOCT6100_G727_40KBPS_3_2: + ulCompType = 0xA; + break; + + case cOCT6100_G727_40KBPS_2_3: + ulCompType = 0x6; + break; + + case cOCT6100_G727_32KBPS_4_0: + ulCompType = 0xE; + break; + + case cOCT6100_G727_32KBPS_3_1: + ulCompType = 0xB; + break; + + case cOCT6100_G727_32KBPS_2_2: + ulCompType = 0x7; + break; + + case cOCT6100_G727_24KBPS_3_0: + ulCompType = 0xC; + break; + + case cOCT6100_G727_24KBPS_2_1: + ulCompType = 0x8; + break; + + case cOCT6100_G727_16KBPS_2_0: + ulCompType = 0x9; + break; + + default: + return cOCT6100_ERR_FATAL_D5; + } + + /* Program the APDCM memory only if ADPCM is requried.*/ + if ( fProgramAdpcmMem == TRUE || f_pChanIndexConf->usPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Set the chariot memory based on the selected port.*/ + if ( f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + usTempTsiMemIndex = f_pChanIndexConf->usRinRoutTsiMemIndex; + + /* Set the codec state flags.*/ + f_pChanIndexConf->fRinRoutCodecActive = TRUE; + + /* Set the conversion memory index to use for compression */ + usConversionMemIndex = f_pChanIndexConf->usRinRoutConversionMemIndex; + } + + else /* f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + usTempTsiMemIndex = f_pChanIndexConf->usSinSoutTsiMemIndex; + + /* Set the codec state flags.*/ + f_pChanIndexConf->fSinSoutCodecActive = TRUE; + + /* Set the conversion memory index to use for compression */ + usConversionMemIndex = f_pChanIndexConf->usSinSoutConversionMemIndex; + } + + ulResult = Oct6100ApiWriteEncoderMemory( f_pApiInstance, + usConversionMemIndex, + ulCompType, + usTempTsiMemIndex, + f_pChannelOpen->CodecConfig.fEnableSilenceSuppression, + f_pChannelOpen->CodecConfig.ulAdpcmNibblePosition, + f_pChanIndexConf->usPhasingTsstIndex, + f_pChannelOpen->CodecConfig.ulPhasingType, + f_pChannelOpen->CodecConfig.ulPhase ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Clearing the tone events bit vector */ + + ulDwordAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_pChanIndexConf->usEchoChanIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ); + ulDwordAddress += cOCT6100_CH_MAIN_TONE_EVENT_OFFSET; + ulDwordData = 0x00000000; + + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulDwordAddress, ulDwordData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulDwordAddress += 4; + + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulDwordAddress, ulDwordData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Write the VQE memory */ + + ulResult = Oct6100ApiWriteVqeMemory( f_pApiInstance, + &f_pChannelOpen->VqeConfig, + f_pChannelOpen, + f_pChanIndexConf->usEchoChanIndex, + f_pChanIndexConf->usEchoMemIndex, + TRUE, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + /*==============================================================================*/ + /* Write the echo memory */ + + ulResult = Oct6100ApiWriteEchoMemory( f_pApiInstance, + pTdmConfig, + f_pChannelOpen, + f_pChanIndexConf->usEchoMemIndex, + f_pChanIndexConf->usRinRoutTsiMemIndex, + f_pChanIndexConf->usSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + + /*==============================================================================*/ + /* Mute channel if required, this is done on a port basis */ + + /* Initialize the silence indexes to invalid for now. */ + pChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + pChanEntry->usSinSilenceEventIndex = cOCT6100_INVALID_INDEX; + + /* Set the TSI memory indexes. */ + pChanEntry->usRinRoutTsiMemIndex = f_pChanIndexConf->usRinRoutTsiMemIndex; + pChanEntry->usSinSoutTsiMemIndex = f_pChanIndexConf->usSinSoutTsiMemIndex; + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, + f_pChanIndexConf->usEchoChanIndex, + f_pChanIndexConf->usRinTsstIndex, + f_pChanIndexConf->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Set the dominant speaker to unassigned, if required. */ + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fDominantSpeakerEnabled == TRUE ) + { + ulResult = Oct6100ApiBridgeSetDominantSpeaker( f_pApiInstance, f_pChanIndexConf->usEchoChanIndex, cOCT6100_CONF_DOMINANT_SPEAKER_UNASSIGNED ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* If necessary, configure the extended tone detection channel.*/ + + if ( f_pChannelOpen->fEnableExtToneDetection == TRUE ) + { + UINT32 ulTempSinLaw; + UINT32 ulTempSoutLaw; + UINT32 ulTempEchoOpMode; + + /* save the original law.*/ + ulTempSinLaw = pTdmConfig->ulSinPcmLaw; + ulTempSoutLaw = pTdmConfig->ulSoutPcmLaw; + ulTempEchoOpMode = f_pChannelOpen->ulEchoOperationMode; + + /* Now, make sure the Sin and Sout law are the same as the Rin law.*/ + + pTdmConfig->ulSinPcmLaw = pTdmConfig->ulRinPcmLaw; + pTdmConfig->ulSoutPcmLaw = pTdmConfig->ulRinPcmLaw; + + f_pChannelOpen->ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_NORMAL; + + /* Write the Echo and VQE memory of the extended channel.*/ + + ulResult = Oct6100ApiWriteDebugChanMemory( f_pApiInstance, + pTdmConfig, + &f_pChannelOpen->VqeConfig, + f_pChannelOpen, + f_pChanIndexConf->usExtToneChanIndex, + f_pChanIndexConf->usExtToneChanIndex, + cOCT6100_API_EXT_TONE_EXTRA_TSI, + f_pChanIndexConf->usExtToneTsiIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now, write the mixer event used to copy the RIN signal of the original channel + into the SIN signal of the exteded channel. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_pChanIndexConf->usExtToneMixerIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= f_pChanIndexConf->usRinRoutTsiMemIndex; + WriteParams.usWriteData |= pTdmConfig->ulRinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = f_pChanIndexConf->usExtToneTsiIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Now insert the Sin copy event into the list.*/ + + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_pChanIndexConf->usExtToneMixerIndex, + cOCT6100_EVENT_TYPE_SIN_COPY, + f_pChanIndexConf->usEchoChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*=======================================================================*/ + + /*==============================================================================*/ + /* Clearing the tone events bit vector */ + + ulDwordAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_pChanIndexConf->usExtToneChanIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ); + ulDwordAddress += cOCT6100_CH_MAIN_TONE_EVENT_OFFSET; + ulDwordData = 0x00000000; + + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulDwordAddress, ulDwordData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulDwordAddress += 4; + + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulDwordAddress, ulDwordData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + /* Write back the original values in the channel open structure.*/ + + pTdmConfig->ulSinPcmLaw = ulTempSinLaw; + pTdmConfig->ulSoutPcmLaw = ulTempSoutLaw; + + f_pChannelOpen->ulEchoOperationMode = ulTempEchoOpMode; + } + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* If necessary, configure the SS tone detection. */ + + for ( ulToneEventNumber = 0; ulToneEventNumber < cOCT6100_MAX_TONE_EVENT; ulToneEventNumber++ ) + { + /* Check if the current tone is a SS tone. */ + ulResult = Oct6100ApiIsSSTone( + f_pApiInstance, + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulToneID, + &fSSTone ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( fSSTone == TRUE ) + { + /* Write to all resources needed to activate tone detection on this SS tone. */ + ulResult = Oct6100ApiWriteToneDetectEvent( + f_pApiInstance, + f_pChanIndexConf->usEchoChanIndex, + ulToneEventNumber, + + cOCT6100_INVALID_INDEX ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Configure the Output Tsst control memory.*/ + + /* Set the ROUT Tsst control entry.*/ + if ( f_pChanIndexConf->usRoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_pChanIndexConf->usRoutTsstIndex, + f_pChannelOpen->CodecConfig.ulAdpcmNibblePosition, + pTdmConfig->ulRoutNumTssts, + f_pChanIndexConf->usRinRoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Set the SOUT Tsst control entry.*/ + if ( f_pChanIndexConf->usSoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_pChanIndexConf->usSoutTsstIndex, + f_pChannelOpen->CodecConfig.ulAdpcmNibblePosition, + pTdmConfig->ulSoutNumTssts, + f_pChanIndexConf->usSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateChannelEntry + +Description: Updates the new channel in the ECHO channel list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelOpen Pointer to echo cancellation channel configuration structure. +f_pChanIndexConf Pointer to a structure used to store the multiple resources indexes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateChannelEntry +UINT32 Oct6100ApiUpdateChannelEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + OUT tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_CHANNEL_OPEN_TDM pTdmConfig; + tPOCT6100_CHANNEL_OPEN_VQE pVqeConfig; + tPOCT6100_CHANNEL_OPEN_CODEC pCodecConfig; + + /* Obtain a pointer to the config structures of the tPOCT6100_CHANNEL_OPEN structure. */ + pTdmConfig = &f_pChannelOpen->TdmConfig; + pVqeConfig = &f_pChannelOpen->VqeConfig; + pCodecConfig = &f_pChannelOpen->CodecConfig; + + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, f_pChanIndexConf->usEchoChanIndex ) + + /*=======================================================================*/ + /* Copy the channel's configuration and allocated resources. */ + pChanEntry->ulUserChanId = f_pChannelOpen->ulUserChanId; + pChanEntry->byEchoOperationMode = (UINT8)( f_pChannelOpen->ulEchoOperationMode & 0xFF ); + pChanEntry->fEnableToneDisabler = (UINT8)( f_pChannelOpen->fEnableToneDisabler & 0xFF ); + pChanEntry->fEnableExtToneDetection = (UINT8)( f_pChannelOpen->fEnableExtToneDetection & 0xFF ); + + /* Save the VQE configuration.*/ + pChanEntry->VqeConfig.byComfortNoiseMode = (UINT8)( pVqeConfig->ulComfortNoiseMode & 0xFF ); + pChanEntry->VqeConfig.fEnableNlp = (UINT8)( pVqeConfig->fEnableNlp & 0xFF ); + pChanEntry->VqeConfig.fEnableTailDisplacement = (UINT8)( pVqeConfig->fEnableTailDisplacement ); + pChanEntry->VqeConfig.usTailDisplacement = (UINT16)( pVqeConfig->ulTailDisplacement & 0xFFFF ); + pChanEntry->VqeConfig.usTailLength = (UINT16)( pVqeConfig->ulTailLength & 0xFFFF ); + + pChanEntry->VqeConfig.fSinDcOffsetRemoval = (UINT8)( pVqeConfig->fSinDcOffsetRemoval & 0xFF ); + pChanEntry->VqeConfig.fRinDcOffsetRemoval = (UINT8)( pVqeConfig->fRinDcOffsetRemoval & 0xFF ); + pChanEntry->VqeConfig.fRinLevelControl = (UINT8)( pVqeConfig->fRinLevelControl & 0xFF ); + pChanEntry->VqeConfig.chRinLevelControlGainDb = (OCT_INT8)( pVqeConfig->lRinLevelControlGainDb & 0xFF ); + pChanEntry->VqeConfig.fSoutLevelControl = (UINT8)( pVqeConfig->fSoutLevelControl & 0xFF ); + pChanEntry->VqeConfig.chSoutLevelControlGainDb = (OCT_INT8)( pVqeConfig->lSoutLevelControlGainDb & 0xFF ); + pChanEntry->VqeConfig.fRinAutomaticLevelControl = (UINT8)( pVqeConfig->fRinAutomaticLevelControl & 0xFF ); + pChanEntry->VqeConfig.chRinAutomaticLevelControlTargetDb = (OCT_INT8)( pVqeConfig->lRinAutomaticLevelControlTargetDb & 0xFF ); + pChanEntry->VqeConfig.fSoutAutomaticLevelControl = (UINT8)( pVqeConfig->fSoutAutomaticLevelControl & 0xFF ); + pChanEntry->VqeConfig.chSoutAutomaticLevelControlTargetDb = (OCT_INT8)( pVqeConfig->lSoutAutomaticLevelControlTargetDb & 0xFF ); + pChanEntry->VqeConfig.fRinHighLevelCompensation = (UINT8)( pVqeConfig->fRinHighLevelCompensation & 0xFF ); + pChanEntry->VqeConfig.chRinHighLevelCompensationThresholdDb = (OCT_INT8)( pVqeConfig->lRinHighLevelCompensationThresholdDb & 0xFF ); + pChanEntry->VqeConfig.fSoutAdaptiveNoiseReduction = (UINT8)( pVqeConfig->fSoutAdaptiveNoiseReduction & 0xFF ); + pChanEntry->VqeConfig.fSoutNoiseBleaching = (UINT8)( pVqeConfig->fSoutNoiseBleaching & 0xFF ); + pChanEntry->VqeConfig.fSoutConferencingNoiseReduction = (UINT8)( pVqeConfig->fSoutConferencingNoiseReduction & 0xFF ); + + pChanEntry->VqeConfig.fAcousticEcho = (UINT8)( pVqeConfig->fAcousticEcho & 0xFF ); + + pChanEntry->VqeConfig.fDtmfToneRemoval = (UINT8)( pVqeConfig->fDtmfToneRemoval & 0xFF ); + + pChanEntry->VqeConfig.chDefaultErlDb = (OCT_INT8)( pVqeConfig->lDefaultErlDb & 0xFF ); + pChanEntry->VqeConfig.chAecDefaultErlDb = (OCT_INT8)( pVqeConfig->lAecDefaultErlDb & 0xFF ); + pChanEntry->VqeConfig.usAecTailLength = (UINT16)( pVqeConfig->ulAecTailLength & 0xFFFF ); + pChanEntry->VqeConfig.byNonLinearityBehaviorA = (UINT8)( pVqeConfig->ulNonLinearityBehaviorA & 0xFF ); + pChanEntry->VqeConfig.byNonLinearityBehaviorB = (UINT8)( pVqeConfig->ulNonLinearityBehaviorB & 0xFF ); + pChanEntry->VqeConfig.byDoubleTalkBehavior = (UINT8)( pVqeConfig->ulDoubleTalkBehavior & 0xFF ); + pChanEntry->VqeConfig.chAnrSnrEnhancementDb = (OCT_INT8)( pVqeConfig->lAnrSnrEnhancementDb & 0xFF ); + pChanEntry->VqeConfig.byAnrVoiceNoiseSegregation = (UINT8)( pVqeConfig->ulAnrVoiceNoiseSegregation & 0xFF ); + pChanEntry->VqeConfig.usToneDisablerVqeActivationDelay = (UINT16)( pVqeConfig->ulToneDisablerVqeActivationDelay & 0xFFFF ); + + pChanEntry->VqeConfig.bySoutAutomaticListenerEnhancementGainDb = (UINT8)( pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb & 0xFF ); + pChanEntry->VqeConfig.bySoutNaturalListenerEnhancementGainDb = (UINT8)( pVqeConfig->ulSoutNaturalListenerEnhancementGainDb & 0xFF ); + pChanEntry->VqeConfig.fSoutNaturalListenerEnhancement = (UINT8)( pVqeConfig->fSoutNaturalListenerEnhancement & 0xFF ); + pChanEntry->VqeConfig.fRoutNoiseReduction = (UINT8)( pVqeConfig->fRoutNoiseReduction & 0xFF ); + pChanEntry->VqeConfig.chRoutNoiseReductionLevelGainDb = (OCT_INT8) (pVqeConfig->lRoutNoiseReductionLevelGainDb & 0xFF); + pChanEntry->VqeConfig.fEnableMusicProtection = (UINT8)( pVqeConfig->fEnableMusicProtection & 0xFF ); + pChanEntry->VqeConfig.fIdleCodeDetection = (UINT8)( pVqeConfig->fIdleCodeDetection & 0xFF ); + + /* Save the codec information.*/ + pChanEntry->CodecConfig.byAdpcmNibblePosition = (UINT8)( pCodecConfig->ulAdpcmNibblePosition & 0xFF ); + + pChanEntry->CodecConfig.byDecoderPort = (UINT8)( pCodecConfig->ulDecoderPort & 0xFF ); + pChanEntry->CodecConfig.byDecodingRate = (UINT8)( pCodecConfig->ulDecodingRate & 0xFF ); + pChanEntry->CodecConfig.byEncoderPort = (UINT8)( pCodecConfig->ulEncoderPort & 0xFF ); + pChanEntry->CodecConfig.byEncodingRate = (UINT8)( pCodecConfig->ulEncodingRate & 0xFF ); + + pChanEntry->CodecConfig.fEnableSilenceSuppression = (UINT8)( pCodecConfig->fEnableSilenceSuppression & 0xFF ); + pChanEntry->CodecConfig.byPhase = (UINT8)( pCodecConfig->ulPhase & 0xFF ); + pChanEntry->CodecConfig.byPhasingType = (UINT8)( pCodecConfig->ulPhasingType & 0xFF ); + + /* Save the RIN settings.*/ + pChanEntry->TdmConfig.byRinPcmLaw = (UINT8)( pTdmConfig->ulRinPcmLaw & 0xFF ); + pChanEntry->TdmConfig.usRinTimeslot = (UINT16)( pTdmConfig->ulRinTimeslot & 0xFFFF ); + pChanEntry->TdmConfig.usRinStream = (UINT16)( pTdmConfig->ulRinStream & 0xFFFF ); + + /* Save the SIN settings.*/ + pChanEntry->TdmConfig.bySinPcmLaw = (UINT8)( pTdmConfig->ulSinPcmLaw & 0xFF ); + pChanEntry->TdmConfig.usSinTimeslot = (UINT16)( pTdmConfig->ulSinTimeslot & 0xFFFF ); + pChanEntry->TdmConfig.usSinStream = (UINT16)( pTdmConfig->ulSinStream & 0xFFFF ); + + /* Save the ROUT settings.*/ + pChanEntry->TdmConfig.byRoutPcmLaw = (UINT8)( pTdmConfig->ulRoutPcmLaw & 0xFF ); + pChanEntry->TdmConfig.usRoutTimeslot = (UINT16)( pTdmConfig->ulRoutTimeslot & 0xFFFF ); + pChanEntry->TdmConfig.usRoutStream = (UINT16)( pTdmConfig->ulRoutStream & 0xFFFF ); + + pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry = cOCT6100_INVALID_INDEX; + pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry = 0; + + /* Save the SOUT settings.*/ + pChanEntry->TdmConfig.bySoutPcmLaw = (UINT8)( pTdmConfig->ulSoutPcmLaw & 0xFF ); + pChanEntry->TdmConfig.usSoutTimeslot = (UINT16)( pTdmConfig->ulSoutTimeslot & 0xFFFF ); + pChanEntry->TdmConfig.usSoutStream = (UINT16)( pTdmConfig->ulSoutStream & 0xFFFF ); + + pChanEntry->TdmConfig.byRinNumTssts = (UINT8)( pTdmConfig->ulRinNumTssts & 0xFF ); + pChanEntry->TdmConfig.bySinNumTssts = (UINT8)( pTdmConfig->ulSinNumTssts & 0xFF ); + pChanEntry->TdmConfig.byRoutNumTssts = (UINT8)( pTdmConfig->ulRoutNumTssts & 0xFF ); + pChanEntry->TdmConfig.bySoutNumTssts = (UINT8)( pTdmConfig->ulSoutNumTssts & 0xFF ); + pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry = cOCT6100_INVALID_INDEX; + pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry = 0; + + /* Save the extended Tone detection information.*/ + pChanEntry->usExtToneChanIndex = f_pChanIndexConf->usExtToneChanIndex; + pChanEntry->usExtToneMixerIndex = f_pChanIndexConf->usExtToneMixerIndex; + pChanEntry->usExtToneTsiIndex = f_pChanIndexConf->usExtToneTsiIndex; + + if ( f_pChannelOpen->fEnableExtToneDetection == TRUE ) + { + tPOCT6100_API_CHANNEL pExtToneChanEntry; + + /* Set the mode of the original channel. He is the channel performing detection on the + SIN port. The extended channel will perform detection on the RIN port.*/ + pChanEntry->ulExtToneChanMode = cOCT6100_API_EXT_TONE_SIN_PORT_MODE; + + /* Now, program the associated channel.*/ + + /* Obtain a pointer to the extended tone detection channel entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pExtToneChanEntry, f_pChanIndexConf->usExtToneChanIndex ); + + pExtToneChanEntry->fReserved = TRUE; + pExtToneChanEntry->ulExtToneChanMode = cOCT6100_API_EXT_TONE_RIN_PORT_MODE; /* Detect on RIN port.*/ + pExtToneChanEntry->usExtToneChanIndex = f_pChanIndexConf->usEchoChanIndex; + + pExtToneChanEntry->aulToneConf[ 0 ] = 0; + pExtToneChanEntry->aulToneConf[ 1 ] = 0; + + } + else + { + /* No extended tone detection supported.*/ + pChanEntry->ulExtToneChanMode = cOCT6100_API_EXT_TONE_DISABLED; + } + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Store hardware related information.*/ + pChanEntry->usRinRoutTsiMemIndex = f_pChanIndexConf->usRinRoutTsiMemIndex; + pChanEntry->usSinSoutTsiMemIndex = f_pChanIndexConf->usSinSoutTsiMemIndex; + pChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + pChanEntry->usExtraRinTsiMemIndex = cOCT6100_INVALID_INDEX; + + /* We are not being tapped for now. */ + pChanEntry->fBeingTapped = FALSE; + + pChanEntry->usTapChanIndex = cOCT6100_INVALID_INDEX; + pChanEntry->usTapBridgeIndex = cOCT6100_INVALID_INDEX; + + /* The copy event has not yet been created. */ + pChanEntry->fCopyEventCreated = FALSE; + + pChanEntry->usRinRoutConversionMemIndex = f_pChanIndexConf->usRinRoutConversionMemIndex; + pChanEntry->usSinSoutConversionMemIndex = f_pChanIndexConf->usSinSoutConversionMemIndex; + + pChanEntry->usPhasingTsstIndex = f_pChanIndexConf->usPhasingTsstIndex; + + pChanEntry->fSinSoutCodecActive = f_pChanIndexConf->fSinSoutCodecActive; + pChanEntry->fRinRoutCodecActive = f_pChanIndexConf->fRinRoutCodecActive; + + + + pChanEntry->usEchoMemIndex = f_pChanIndexConf->usEchoMemIndex; + + pChanEntry->usRinTsstIndex = f_pChanIndexConf->usRinTsstIndex; + pChanEntry->usSinTsstIndex = f_pChanIndexConf->usSinTsstIndex; + pChanEntry->usRoutTsstIndex = f_pChanIndexConf->usRoutTsstIndex; + pChanEntry->usSoutTsstIndex = f_pChanIndexConf->usSoutTsstIndex; + + pChanEntry->usSinCopyEventIndex = cOCT6100_INVALID_INDEX; + pChanEntry->usSoutCopyEventIndex = cOCT6100_INVALID_INDEX; + + /* Nothing muted for now. */ + pChanEntry->usMutedPorts = cOCT6100_CHANNEL_MUTE_PORT_NONE; + + /* Set all the GW feature initial value.*/ + /* Bridge info */ + pChanEntry->usBridgeIndex = cOCT6100_INVALID_INDEX; + pChanEntry->fMute = FALSE; + + pChanEntry->usLoadEventIndex = cOCT6100_INVALID_INDEX; + pChanEntry->usSubStoreEventIndex = cOCT6100_INVALID_INDEX; + + /* Buffer playout info.*/ + pChanEntry->fRinBufPlaying = FALSE; + pChanEntry->fSoutBufPlaying = FALSE; + + /* Tone detection state. */ + /* This array is configured as follow.*/ + /* Index 0 contain event 0 to 31 (msb = event 31) and Index 1 contain index 32 - 55 */ + pChanEntry->aulToneConf[ 0 ] = 0; + pChanEntry->aulToneConf[ 1 ] = 0; + pChanEntry->ulLastSSToneDetected = (PTR_TYPE)cOCT6100_INVALID_VALUE; + pChanEntry->ulLastSSToneTimestamp = (PTR_TYPE)cOCT6100_INVALID_VALUE; + + /* Initialize the bidirectional flag.*/ + pChanEntry->fBiDirChannel = FALSE; + + /*=======================================================================*/ + /* Init some of the stats.*/ + + pChanEntry->sMaxERL = cOCT6100_INVALID_SIGNED_STAT_W; + pChanEntry->sMaxERLE = cOCT6100_INVALID_SIGNED_STAT_W; + pChanEntry->usMaxEchoDelay = cOCT6100_INVALID_STAT_W; + pChanEntry->usNumEchoPathChangesOfst = 0; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Update the dependency of the phasing TSST if one is associated to the chanel.*/ + + if ( f_pChanIndexConf->usPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + { + tPOCT6100_API_PHASING_TSST pPhasingEntry; + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPhasingEntry, f_pChanIndexConf->usPhasingTsstIndex ); + + pPhasingEntry->usDependencyCnt++; + } + /*=======================================================================*/ + + /*=======================================================================*/ + + /* Form handle returned to user. */ + *f_pChannelOpen->pulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | (pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_pChanIndexConf->usEchoChanIndex; + + /* Finally, mark the channel as open. */ + pChanEntry->fReserved = TRUE; + pChanEntry->usExtraSinTsiDependencyCnt = 0; + + /* Increment the number of channel open.*/ + f_pApiInstance->pSharedInfo->ChipStats.usNumberChannels++; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelCloseSer + +Description: Closes a echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelClose Pointer to echo cancellation channel close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelCloseSer +UINT32 Oct6100ChannelCloseSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_CLOSE f_pChannelClose ) +{ + UINT16 usChannelIndex; + + + UINT32 ulResult; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertChannelParams( f_pApiInstance, + f_pChannelClose, + + &usChannelIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the echo cancellation channel. */ + ulResult = Oct6100ApiInvalidateChannelStructs( f_pApiInstance, + + usChannelIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the echo cancellation channel. */ + ulResult = Oct6100ApiReleaseChannelResources( f_pApiInstance, usChannelIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Invalidate the handle.*/ + f_pChannelClose->ulChannelHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertChannelParams + +Description: Validate the handle given by the user and verify the state of + the channel about to be closed. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelClose Pointer to echo cancellation channel close structure. +f_pulFpgaChanIndex Pointer to the FPGA channel index associated to this channel. +f_pusChanIndex Pointer to the index of the channel within the API instance. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertChannelParams +UINT32 Oct6100ApiAssertChannelParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_CLOSE f_pChannelClose, + + IN OUT PUINT16 f_pusChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pChannelClose->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + *f_pusChanIndex = (UINT16)( f_pChannelClose->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, *f_pusChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelClose->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + if ( pChanEntry->fBiDirChannel == TRUE ) + return cOCT6100_ERR_CHANNEL_PART_OF_BIDIR_CHANNEL; + + /*=======================================================================*/ + + /* Check if the channel is bound to a bridge. */ + if ( pChanEntry->usBridgeIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_ACTIVE_DEPENDENCIES; + + + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInvalidateChannelStructs + +Description: Closes a echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulFpgaChanIndex Index of the channel within the SCN_PLC FPGA. +f_usChanIndex Index of the channel within the API instance. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInvalidateChannelStructs +UINT32 Oct6100ApiInvalidateChannelStructs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + + IN UINT16 f_usChanIndex ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_CHANNEL_TDM pTdmConfig; + tPOCT6100_API_TSST_ENTRY pTsstEntry; + tOCT6100_BUFFER_PLAYOUT_STOP BufferPlayoutStop; + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_WRITE_SMEAR_PARAMS SmearParams; + UINT32 ulResult; + UINT16 usCurrentEntry; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ); + + /* Obtain local pointer to the TDM configuration of the channel */ + pTdmConfig = &pChanEntry->TdmConfig; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + SmearParams.pProcessContext = f_pApiInstance->pProcessContext; + + SmearParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* If this channel is currently debugged, automatically close the debug channel. */ + if ( ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + && ( pSharedInfo->DebugInfo.usCurrentDebugChanIndex == f_usChanIndex ) ) + { + tOCT6100_DEBUG_SELECT_CHANNEL SelectDebugChan; + + /* Ensure forward compatibility. */ + Oct6100DebugSelectChannelDef( &SelectDebugChan ); + + /* Set the hot channel to an invalid handle to disable recording. */ + SelectDebugChan.ulChannelHndl = cOCT6100_INVALID_HANDLE; + + /* Call the serialized fonction. */ + ulResult = Oct6100DebugSelectChannelSer( f_pApiInstance, &SelectDebugChan, FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Deactivate the TSST control memory if used. */ + + /* RIN port.*/ + if ( pTdmConfig->usRinTimeslot != cOCT6100_UNASSIGNED ) + { + /* Deactivate the TSST entry.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( pChanEntry->usRinTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* SIN port.*/ + if ( pTdmConfig->usSinTimeslot != cOCT6100_UNASSIGNED ) + { + /* Deactivate the TSST entry.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( pChanEntry->usSinTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*=======================================================================*/ + /* ROUT port.*/ + + if ( pTdmConfig->usRoutTimeslot != cOCT6100_UNASSIGNED ) + { + /* Deactivate the TSST entry.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( pChanEntry->usRoutTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Now the broadcast TSST.*/ + usCurrentEntry = pTdmConfig->usRoutBrdcastTsstFirstEntry; + while( usCurrentEntry != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( pSharedInfo, pTsstEntry, usCurrentEntry ); + + /* Deactivate the TSST entry.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (pTsstEntry->usTsstMemoryIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move to the next entry.*/ + usCurrentEntry = pTsstEntry->usNextEntry; + } + /*=======================================================================*/ + + /*=======================================================================*/ + /* SOUT port.*/ + + if ( pTdmConfig->usSoutTimeslot != cOCT6100_UNASSIGNED ) + { + /* Deactivate the TSST entry.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( pChanEntry->usSoutTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Now the broadcast TSST.*/ + usCurrentEntry = pTdmConfig->usSoutBrdcastTsstFirstEntry; + while( usCurrentEntry != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( pSharedInfo, pTsstEntry, usCurrentEntry ); + + /* Deactivate the TSST entry.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (pTsstEntry->usTsstMemoryIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move to the next entry.*/ + usCurrentEntry = pTsstEntry->usNextEntry; + } + /*=======================================================================*/ + + + /*------------------------------------------------------------------------------*/ + /* Deactivate the ECHO control memory entry.*/ + + /* Set the input Echo control entry to unused.*/ + WriteParams.ulWriteAddress = cOCT6100_ECHO_CONTROL_MEM_BASE + ( pChanEntry->usEchoMemIndex * cOCT6100_ECHO_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x85FF; /* TSI index 1535 reserved for power-down mode */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = 0xC5FF; /* TSI index 1535 reserved for power-down mode */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*------------------------------------------------------------------------------*/ + + /*------------------------------------------------------------------------------*/ + /* Deactivate the conversion control memories if used. */ + + if ( pChanEntry->usRinRoutConversionMemIndex != cOCT6100_INVALID_INDEX ) + { + /* Rin/Rout stream conversion memory was used */ + ulResult = Oct6100ApiClearConversionMemory( f_pApiInstance, pChanEntry->usRinRoutConversionMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pChanEntry->usSinSoutConversionMemIndex != cOCT6100_INVALID_INDEX ) + { + /* Sin/Sout stream conversion memory was used */ + ulResult = Oct6100ApiClearConversionMemory( f_pApiInstance, pChanEntry->usSinSoutConversionMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*------------------------------------------------------------------------------*/ + + + /*------------------------------------------------------------------------------*/ + /* Clear the silence copy events if they were created. */ + + /* Unmute the Rin port if it was muted. */ + if ( pChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_DF; + + pChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + + /* Unmute the Sin port if it was muted. */ + if ( pChanEntry->usSinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pChanEntry->usSinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pChanEntry->usSinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_E0; + + pChanEntry->usSinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + + /*------------------------------------------------------------------------------*/ + + /* Synch all the buffer playout field.*/ + if ( pSharedInfo->ImageInfo.fBufferPlayout == TRUE ) + { + Oct6100BufferPlayoutStopDef( &BufferPlayoutStop ); + + BufferPlayoutStop.ulChannelHndl = cOCT6100_INVALID_HANDLE; + BufferPlayoutStop.fStopCleanly = FALSE; + + BufferPlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + ulResult = Oct6100ApiInvalidateChanPlayoutStructs( + f_pApiInstance, + &BufferPlayoutStop, + f_usChanIndex, + pChanEntry->usEchoMemIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + BufferPlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_SOUT; + ulResult = Oct6100ApiInvalidateChanPlayoutStructs( + f_pApiInstance, + &BufferPlayoutStop, + f_usChanIndex, + pChanEntry->usEchoMemIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + + + + + /* Free all resources reserved for extended tone detection.*/ + if ( pChanEntry->fEnableExtToneDetection == TRUE ) + { + /*------------------------------------------------------------------------------*/ + /* Deactivate the ECHO control memory entry of the extended channel.*/ + + /* Set the input Echo control entry to unused.*/ + WriteParams.ulWriteAddress = cOCT6100_ECHO_CONTROL_MEM_BASE + ( pChanEntry->usExtToneChanIndex * cOCT6100_ECHO_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x85FF; /* TSI index 1535 reserved for power-down mode */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = 0xC5FF; /* TSI index 1535 reserved for power-down mode */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*------------------------------------------------------------------------------*/ + + /*------------------------------------------------------------------------------*/ + /* Remove the mixer event used to copy the RIN signal to the SIN port of the extended + channel.*/ + + /* Clear the Copy event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pChanEntry->usExtToneMixerIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pChanEntry->usExtToneMixerIndex, + cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + } + + /*------------------------------------------------------------------------------*/ + /* Reset PGSP */ + + WriteParams.ulWriteAddress = cOCT6100_CHANNEL_ROOT_BASE + ( pChanEntry->usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + WriteParams.usWriteData = 0x0800; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + /*------------------------------------------------------------------------------*/ + /* Clear the mute with feature bit. */ + + if ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) + { + ulResult = Oct6100ApiMuteSinWithFeatures( f_pApiInstance, f_usChanIndex, FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*------------------------------------------------------------------------------*/ + + /*------------------------------------------------------------------------------*/ + /* Clear the VQE memory. */ + + SmearParams.ulWriteAddress = cOCT6100_CHANNEL_ROOT_BASE + ( pChanEntry->usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst + 0x20; + SmearParams.usWriteData = 0x0000; + SmearParams.ulWriteLength = 2; + + mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + /*------------------------------------------------------------------------------*/ + /* Clear the NLP memory. */ + + SmearParams.ulWriteAddress = cOCT6100_CHANNEL_ROOT_BASE + ( pChanEntry->usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst + 0x28; + SmearParams.usWriteData = 0x0000; + SmearParams.ulWriteLength = 2; + + mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + /* Clear the AF information memory. */ + + SmearParams.ulWriteAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( pChanEntry->usEchoMemIndex * f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst; + SmearParams.usWriteData = 0x0000; + SmearParams.ulWriteLength = 12; + + mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*Reset ALC status*/ + WriteParams.ulWriteAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( pChanEntry->usEchoMemIndex * f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst + 0x3A; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseChannelResources + +Description: Release and clear the API entry associated to the echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usChannelIndex Index of the echo cancellation channel in the API list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseChannelResources +UINT32 Oct6100ApiReleaseChannelResources( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChannelIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_CHANNEL_TDM pTdmConfig; + tPOCT6100_API_TSST_ENTRY pTsstEntry; + UINT32 ulResult; + UINT16 usCurrentEntry; + UINT32 ulTimeslot; + UINT32 ulStream; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChannelIndex ); + + /* Obtain local pointer to the TDM configurationof the channel */ + pTdmConfig = &pChanEntry->TdmConfig; + + /* Release the two TSI chariot memory entries.*/ + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pChanEntry->usRinRoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_2; + + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pChanEntry->usSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_3; + + /* Now release the ECHO channel and control memory entries.*/ + ulResult = Oct6100ApiReleaseEchoEntry( f_pApiInstance, f_usChannelIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_4; + + /* Release the conversion resources.*/ + if ( pChanEntry->usRinRoutConversionMemIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, pChanEntry->usRinRoutConversionMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_B9; + + pChanEntry->usRinRoutConversionMemIndex = cOCT6100_INVALID_INDEX; + } + + if ( pChanEntry->usSinSoutConversionMemIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, pChanEntry->usSinSoutConversionMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_BA; + + pChanEntry->usSinSoutConversionMemIndex = cOCT6100_INVALID_INDEX; + } + + /*=========================================================================*/ + /* Release the TSST control memory entries if any were reserved.*/ + if ( pTdmConfig->usRinTimeslot != cOCT6100_UNASSIGNED) + { + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->usRinTimeslot, + pTdmConfig->usRinStream, + pTdmConfig->byRinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_5; + } + + if ( pTdmConfig->usSinTimeslot != cOCT6100_UNASSIGNED) + { + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->usSinTimeslot, + pTdmConfig->usSinStream, + pTdmConfig->bySinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_6; + } + + /*=======================================================================*/ + /* Release all the TSSTs associated to the ROUT port of this channel. */ + if ( pTdmConfig->usRoutTimeslot != cOCT6100_UNASSIGNED) + { + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->usRoutTimeslot, + pTdmConfig->usRoutStream, + pTdmConfig->byRoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_7; + } + + /* Now release the Broadcast TSSTs. */ + usCurrentEntry = pTdmConfig->usRoutBrdcastTsstFirstEntry; + while( usCurrentEntry != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( pSharedInfo, pTsstEntry, usCurrentEntry ); + + ulTimeslot = pTsstEntry->usTsstValue >> 5; + ulStream = pTsstEntry->usTsstValue & 0x1F; + + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + ulTimeslot, + ulStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_OUTPUT_TSST, + usCurrentEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_8; + + /* Move to the next entry.*/ + usCurrentEntry = pTsstEntry->usNextEntry; + + /* Invalidate the current entry.*/ + pTsstEntry->usTsstMemoryIndex = 0xFFFF; + pTsstEntry->usTsstValue = 0xFFFF; + pTsstEntry->usNextEntry = cOCT6100_INVALID_INDEX; + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Release all the TSSTs associated to the SOUT port of this channel. */ + if ( pTdmConfig->usSoutTimeslot != cOCT6100_UNASSIGNED) + { + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->usSoutTimeslot, + pTdmConfig->usSoutStream, + pTdmConfig->bySoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_9; + } + + /* Now release the Broadcast TSSTs. */ + usCurrentEntry = pTdmConfig->usSoutBrdcastTsstFirstEntry; + while( usCurrentEntry != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( pSharedInfo, pTsstEntry, usCurrentEntry ); + + ulTimeslot = pTsstEntry->usTsstValue >> 5; + ulStream = pTsstEntry->usTsstValue & 0x1F; + + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + ulTimeslot, + ulStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_OUTPUT_TSST, + usCurrentEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A; + + /* Move to the next entry.*/ + usCurrentEntry = pTsstEntry->usNextEntry; + + /* Invalidate the current entry.*/ + pTsstEntry->usTsstMemoryIndex = 0xFFFF; + pTsstEntry->usTsstValue = 0xFFFF; + pTsstEntry->usNextEntry = cOCT6100_INVALID_INDEX; + } + /*=======================================================================*/ + + /*=======================================================================*/ + /* Update the dependency of the phasing TSST if one is associated to the chanel.*/ + + if ( pChanEntry->usPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + { + tPOCT6100_API_PHASING_TSST pPhasingEntry; + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPhasingEntry, pChanEntry->usPhasingTsstIndex ); + + pPhasingEntry->usDependencyCnt--; + } + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Release any resources reserved for the extended tone detection.*/ + + if ( pChanEntry->fEnableExtToneDetection == TRUE ) + { + tPOCT6100_API_CHANNEL pExtToneChanEntry; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pExtToneChanEntry, pChanEntry->usExtToneChanIndex ); + + /* Release the ECHO channel and control memory entries.*/ + ulResult = Oct6100ApiReleaseEchoEntry( f_pApiInstance, pChanEntry->usExtToneChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_C1; + + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pChanEntry->usExtToneTsiIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_C2; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pChanEntry->usExtToneMixerIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_C3; + + /* Now release the channel entry */ + pExtToneChanEntry->ulExtToneChanMode = cOCT6100_API_EXT_TONE_DISABLED; + pExtToneChanEntry->fReserved = FALSE; + + /* Set the current entry to disable, just in case.*/ + pChanEntry->ulExtToneChanMode = cOCT6100_API_EXT_TONE_DISABLED; + } + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Update the channel's list entry. */ + + /* Clear the NLP dword array. */ + Oct6100UserMemSet( pChanEntry->aulNlpConfDword, 0, sizeof( pChanEntry->aulNlpConfDword ) ); + + /* Clear the echo operation mode. */ + pChanEntry->byEchoOperationMode = cOCT6100_ECHO_OP_MODE_POWER_DOWN; + + /* Mark the channel as closed. */ + pChanEntry->fReserved = FALSE; + pChanEntry->byEntryOpenCnt++; + + /* Reset the port, the bridge and BidirInfo */ + pChanEntry->usMutedPorts = cOCT6100_CHANNEL_MUTE_PORT_NONE; + pChanEntry->fBiDirChannel = FALSE; + pChanEntry->usBridgeIndex = cOCT6100_INVALID_INDEX; + + /* Decrement the number of channel open.*/ + f_pApiInstance->pSharedInfo->ChipStats.usNumberChannels--; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; + +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelModifySer + +Description: Modify an echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelModify Pointer to channel configuration structure. The handle + identifying the buffer in all future function calls is + returned in this structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelModifySer +UINT32 Oct6100ChannelModifySer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_MODIFY f_pChannelModify ) +{ + UINT16 usChanIndex; + UINT32 ulResult; + UINT16 usNewRinTsstIndex; + UINT16 usNewSinTsstIndex; + UINT16 usNewRoutTsstIndex; + UINT16 usNewSoutTsstIndex; + UINT8 fSinSoutCodecActive = FALSE; + UINT8 fRinRoutCodecActive = FALSE; + UINT16 usNewPhasingTsstIndex; + tOCT6100_CHANNEL_OPEN *pTempChanOpen; + + /* We don't want this 290 byte structure on the stack */ + pTempChanOpen = kmalloc(sizeof(*pTempChanOpen), GFP_ATOMIC); + if (!pTempChanOpen) + return cOCT6100_ERR_FATAL_0; + + /* Check the user's configuration of the echo cancellation channel for errors. */ + ulResult = Oct6100ApiCheckChannelModify( f_pApiInstance, + f_pChannelModify, + pTempChanOpen, + &usNewPhasingTsstIndex, + &usChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + goto out; + + /* Reserve all resources needed by the echo cancellation channel. */ + ulResult = Oct6100ApiModifyChannelResources( f_pApiInstance, + f_pChannelModify, + usChanIndex, + &usNewRinTsstIndex, + &usNewSinTsstIndex, + &usNewRoutTsstIndex, + &usNewSoutTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + goto out; + + /* Write all necessary structures to activate the echo cancellation channel. */ + ulResult = Oct6100ApiModifyChannelStructs( f_pApiInstance, + f_pChannelModify, + pTempChanOpen, + usChanIndex, + usNewPhasingTsstIndex, + &fSinSoutCodecActive, + &fRinRoutCodecActive, + usNewRinTsstIndex, + usNewSinTsstIndex, + usNewRoutTsstIndex, + usNewSoutTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + goto out; + + /* Update the new echo cancellation channels's entry in the ECHO channel list. */ + ulResult = Oct6100ApiModifyChannelEntry( f_pApiInstance, + f_pChannelModify, + pTempChanOpen, + usChanIndex, + usNewPhasingTsstIndex, + fSinSoutCodecActive, + fRinRoutCodecActive, + usNewRinTsstIndex, + usNewSinTsstIndex, + usNewRoutTsstIndex, + usNewSoutTsstIndex ); +out: + kfree(pTempChanOpen); + + return ulResult; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckChannelModify + +Description: Checks the user's echo cancellation channel modify structure for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelModify Pointer to echo cancellation channel modify structure. +f_pTempChanOpen Pointer to a channel open structure. +f_pusNewPhasingTsstIndex Pointer to a new phasing TSST index within the API instance. +f_pusChanIndex Pointer to the channel index within the API instance channel list + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckChannelModify +UINT32 Oct6100ApiCheckChannelModify( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_MODIFY f_pChannelModify, + IN tPOCT6100_CHANNEL_OPEN f_pTempChanOpen, + OUT PUINT16 f_pusNewPhasingTsstIndex, + OUT PUINT16 f_pusChanIndex ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulResult; + UINT32 ulEntryOpenCnt; + UINT32 ulDecoderNumTssts; + + /* Check the provided handle. */ + if ( (f_pChannelModify->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + *f_pusChanIndex = (UINT16)( f_pChannelModify->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChanIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, *f_pusChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelModify->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Check the general modify parameters. */ + + if ( f_pChannelModify->ulEchoOperationMode != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_NORMAL && + f_pChannelModify->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_HT_FREEZE && + f_pChannelModify->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_HT_RESET && + f_pChannelModify->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_POWER_DOWN && + f_pChannelModify->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_EXTERNAL && + f_pChannelModify->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION && + f_pChannelModify->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_NO_ECHO ) + return cOCT6100_ERR_CHANNEL_ECHO_OP_MODE; + + /* Check the 2100Hz echo disabling configuration.*/ + if ( f_pChannelModify->fEnableToneDisabler != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->fEnableToneDisabler != TRUE && + f_pChannelModify->fEnableToneDisabler != FALSE ) + return cOCT6100_ERR_CHANNEL_TONE_DISABLER_ENABLE; + + /* Check the disable tone detection flag. */ + if ( f_pChannelModify->fDisableToneDetection != TRUE && + f_pChannelModify->fDisableToneDetection != FALSE ) + return cOCT6100_ERR_CHANNEL_DISABLE_TONE_DETECTION; + + /* Check the stop buffer playout flag. */ + if ( f_pChannelModify->fStopBufferPlayout != TRUE && + f_pChannelModify->fStopBufferPlayout != FALSE ) + return cOCT6100_ERR_CHANNEL_STOP_BUFFER_PLAYOUT; + + /* Check the remove conference bridge participant flag. */ + if ( f_pChannelModify->fRemoveConfBridgeParticipant != TRUE && + f_pChannelModify->fRemoveConfBridgeParticipant != FALSE ) + return cOCT6100_ERR_CHANNEL_REMOVE_CONF_BRIDGE_PARTICIPANT; + + /* Check the remove broadcast timeslots flag. */ + if ( f_pChannelModify->fRemoveBroadcastTssts != TRUE && + f_pChannelModify->fRemoveBroadcastTssts != FALSE ) + return cOCT6100_ERR_CHANNEL_REMOVE_BROADCAST_TSSTS; + + if ( f_pChannelModify->fCodecConfigModified != TRUE && + f_pChannelModify->fCodecConfigModified != FALSE ) + return cOCT6100_ERR_CHANNEL_MODIFY_CODEC_CONFIG; + + if ( f_pChannelModify->fVqeConfigModified != TRUE && + f_pChannelModify->fVqeConfigModified != FALSE ) + return cOCT6100_ERR_CHANNEL_MODIFY_VQE_CONFIG; + + if ( f_pChannelModify->fTdmConfigModified != TRUE && + f_pChannelModify->fTdmConfigModified != FALSE ) + return cOCT6100_ERR_CHANNEL_MODIFY_TDM_CONFIG; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Verify if any law change was requested. If so reprogram all structures.*/ + + if (( f_pChannelModify->fTdmConfigModified == TRUE ) && + ( f_pChannelModify->TdmConfig.ulRinPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->TdmConfig.ulSinPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->TdmConfig.ulRoutPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->TdmConfig.ulSoutPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING )) + { + f_pChannelModify->fVqeConfigModified = TRUE; + f_pChannelModify->fCodecConfigModified = TRUE; + } + /*=======================================================================*/ + + ulResult = Oct6100ApiUpdateOpenStruct( f_pApiInstance, f_pChannelModify, f_pTempChanOpen, pChanEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* All further check will now be performed using the TempOpenChan structure in order + to reuse the checks written for the open channel structure.*/ + + + + /* Check the TDM config.*/ + if ( f_pChannelModify->fTdmConfigModified == TRUE ) + { + tPOCT6100_CHANNEL_OPEN_TDM pOpenTdm; + + pOpenTdm = &f_pTempChanOpen->TdmConfig; + + ulResult = Oct6100ApiCheckTdmConfig( f_pApiInstance, + pOpenTdm ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if that Stream and Timeslot values are valid.*/ + + /* Check the RIN port.*/ + if ( f_pChannelModify->TdmConfig.ulRinStream == cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulRinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_RIN_TIMESLOT; + + if ( f_pChannelModify->TdmConfig.ulRinStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulRinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_RIN_STREAM; + + if ( pChanEntry->fBeingTapped == TRUE ) + { + /* Check that the Rin stream + timeslot are not being assigned. */ + if ( f_pChannelModify->TdmConfig.ulRinStream != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( f_pChannelModify->TdmConfig.ulRinStream != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_RIN_STREAM; + + if ( f_pChannelModify->TdmConfig.ulRinTimeslot != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_RIN_TIMESLOT; + } + } + + /* Check the SIN port.*/ + if ( f_pChannelModify->TdmConfig.ulSinStream == cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulSinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_SIN_TIMESLOT; + + if ( f_pChannelModify->TdmConfig.ulSinStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulSinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_SIN_STREAM; + + /* Check the ROUT port.*/ + if ( f_pChannelModify->TdmConfig.ulRoutStream == cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulRoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_ROUT_TIMESLOT; + + if ( f_pChannelModify->TdmConfig.ulRoutStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulRoutTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_ROUT_STREAM; + + /* Check the SOUT port.*/ + if ( f_pChannelModify->TdmConfig.ulSoutStream == cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulSoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_SOUT_TIMESLOT; + + if ( f_pChannelModify->TdmConfig.ulSoutStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulSoutTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_SOUT_STREAM; + + /* Verify if the channel is currently part of a bidirectional channel, and if */ + /* so perform the required checks. */ + if ( pChanEntry->fBiDirChannel == TRUE ) + { + /* Check the ports that must remain unassigned.*/ + if ( f_pTempChanOpen->TdmConfig.ulRinTimeslot != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_RIN_TIMESLOT; + if ( f_pTempChanOpen->TdmConfig.ulSoutTimeslot != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_SOUT_TIMESLOT; + + /* Check that no PCM law change is requested.*/ + if ( f_pTempChanOpen->TdmConfig.ulRinPcmLaw != f_pTempChanOpen->TdmConfig.ulRoutPcmLaw ) + return cOCT6100_ERR_CHANNEL_RIN_ROUT_LAW_CONVERSION; + if ( f_pTempChanOpen->TdmConfig.ulSinPcmLaw != f_pTempChanOpen->TdmConfig.ulSoutPcmLaw ) + return cOCT6100_ERR_CHANNEL_SIN_SOUT_LAW_CONVERSION; + } + + /* If this channel is on a conference bridge, a few more things must be checked. */ + if ( pChanEntry->usBridgeIndex != cOCT6100_INVALID_INDEX ) + { + /* If conferencing, law conversion cannot be applied. */ + /* This check is done only if both input and output ports are assigned. */ + if ( ( f_pTempChanOpen->TdmConfig.ulRinTimeslot != cOCT6100_UNASSIGNED ) + && ( f_pTempChanOpen->TdmConfig.ulRoutTimeslot != cOCT6100_UNASSIGNED ) ) + { + /* Laws must be the same! */ + if ( f_pTempChanOpen->TdmConfig.ulRinPcmLaw != f_pTempChanOpen->TdmConfig.ulRoutPcmLaw ) + return cOCT6100_ERR_CHANNEL_RIN_ROUT_LAW_CONVERSION; + } + + /* Check for Sin. */ + if ( ( f_pTempChanOpen->TdmConfig.ulSinTimeslot != cOCT6100_UNASSIGNED ) + && ( f_pTempChanOpen->TdmConfig.ulSoutTimeslot != cOCT6100_UNASSIGNED ) ) + { + /* Laws must be the same! */ + if ( f_pTempChanOpen->TdmConfig.ulSinPcmLaw != f_pTempChanOpen->TdmConfig.ulSoutPcmLaw ) + return cOCT6100_ERR_CHANNEL_SIN_SOUT_LAW_CONVERSION; + } + + /* Check if ADPCM is requested. */ + if ( f_pTempChanOpen->CodecConfig.ulEncoderPort != cOCT6100_NO_ENCODING && + f_pTempChanOpen->CodecConfig.ulEncodingRate != cOCT6100_G711_64KBPS ) + { + /* No ADPCM in a conference bridge! */ + return cOCT6100_ERR_CHANNEL_ENCODING_RATE; + } + + if ( f_pTempChanOpen->CodecConfig.ulDecoderPort != cOCT6100_NO_DECODING && + f_pTempChanOpen->CodecConfig.ulDecodingRate != cOCT6100_G711_64KBPS ) + { + /* No ADPCM in a conference bridge! */ + return cOCT6100_ERR_CHANNEL_DECODING_RATE; + } + } + + if ( f_pTempChanOpen->CodecConfig.ulEncoderPort == cOCT6100_NO_ENCODING || + f_pTempChanOpen->CodecConfig.ulDecoderPort == cOCT6100_NO_DECODING ) + { + /* Make sure no law conversion is attempted since it is not supported by the device.*/ + if ( f_pTempChanOpen->TdmConfig.ulRinPcmLaw != f_pTempChanOpen->TdmConfig.ulRoutPcmLaw ) + return cOCT6100_ERR_CHANNEL_RIN_ROUT_LAW_CONVERSION; + if ( f_pTempChanOpen->TdmConfig.ulSinPcmLaw != f_pTempChanOpen->TdmConfig.ulSoutPcmLaw ) + return cOCT6100_ERR_CHANNEL_SIN_SOUT_LAW_CONVERSION; + } + + if ( pChanEntry->fEnableExtToneDetection == TRUE && + f_pTempChanOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + return cOCT6100_ERR_CHANNEL_EXT_TONE_DETECTION_DECODER_PORT; + + /* A few special checks must be done if the configuration is to be applied */ + /* to all opened channels. */ + if ( f_pChannelModify->fApplyToAllChannels == TRUE ) + { + /* When the configuration to be applied is for all channels, */ + /* check that the stream and timeslot parameters are not being assigned. */ + + /* Check the Rout port. */ + if ( f_pChannelModify->TdmConfig.ulRoutStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulRoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Check that the Rout ports is being unassigned. */ + if ( f_pTempChanOpen->TdmConfig.ulRoutStream != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_ROUT_STREAM_UNASSIGN; + if ( f_pTempChanOpen->TdmConfig.ulRoutTimeslot != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_ROUT_TIMESLOT_UNASSIGN; + } + + /* Check the Rin port. */ + if ( f_pChannelModify->TdmConfig.ulRinStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulRinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Check that the Rin ports is being unassigned. */ + if ( f_pTempChanOpen->TdmConfig.ulRinStream != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_RIN_STREAM_UNASSIGN; + if ( f_pTempChanOpen->TdmConfig.ulRinTimeslot != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_RIN_TIMESLOT_UNASSIGN; + } + + /* Check the Sout port. */ + if ( f_pChannelModify->TdmConfig.ulSoutStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulSoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Check that the Sout ports is being unassigned. */ + if ( f_pTempChanOpen->TdmConfig.ulSoutStream != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_SOUT_STREAM_UNASSIGN; + if ( f_pTempChanOpen->TdmConfig.ulSoutTimeslot != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_SOUT_TIMESLOT_UNASSIGN; + } + + /* Check the Sin port. */ + if ( f_pChannelModify->TdmConfig.ulSinStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulSinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Check that the Sin ports is being unassigned. */ + if ( f_pTempChanOpen->TdmConfig.ulSinStream != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_SIN_STREAM_UNASSIGN; + if ( f_pTempChanOpen->TdmConfig.ulSinTimeslot != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_SIN_TIMESLOT_UNASSIGN; + } + } + } + + /* Check the VQE config.*/ + if ( f_pChannelModify->fVqeConfigModified == TRUE ) + { + ulResult = Oct6100ApiCheckVqeConfig( f_pApiInstance, + &f_pTempChanOpen->VqeConfig, + f_pTempChanOpen->fEnableToneDisabler ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Verify if the echo operation mode selected can be applied. */ + if ( ( f_pTempChanOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_NO_ECHO ) + && ( f_pTempChanOpen->VqeConfig.fEnableNlp == FALSE ) ) + return cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_NLP_REQUIRED; + + if ( ( f_pTempChanOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) + && ( f_pTempChanOpen->VqeConfig.fEnableNlp == FALSE ) ) + return cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_NLP_REQUIRED; + + /* Comfort noise must be activated for speech recognition mode to work. */ + if ( ( f_pTempChanOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) + && ( f_pTempChanOpen->VqeConfig.ulComfortNoiseMode == cOCT6100_COMFORT_NOISE_OFF ) ) + return cOCT6100_ERR_CHANNEL_COMFORT_NOISE_REQUIRED; + + /* Check the Codec config.*/ + if ( f_pChannelModify->fCodecConfigModified == TRUE ) + { + if ( f_pTempChanOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + ulDecoderNumTssts = f_pTempChanOpen->TdmConfig.ulRinNumTssts; + else /* f_pTempChanOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN */ + ulDecoderNumTssts = f_pTempChanOpen->TdmConfig.ulSinNumTssts; + + ulResult = Oct6100ApiCheckCodecConfig( f_pApiInstance, + &f_pTempChanOpen->CodecConfig, + ulDecoderNumTssts, + f_pusNewPhasingTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + + /* make sure that if silence suppression is activated, the NLP is enabled.*/ + if ( f_pTempChanOpen->CodecConfig.fEnableSilenceSuppression == TRUE && f_pTempChanOpen->VqeConfig.fEnableNlp == FALSE ) + return cOCT6100_ERR_CHANNEL_SIL_SUP_NLP_MUST_BE_ENABLED; + + /* Verify if the channel is currently part of a bidirectional channel, and if so perform + the required checks.*/ + if ( pChanEntry->fBiDirChannel == TRUE ) + { + /* Check the ports that must remain unassigned.*/ + if ( f_pTempChanOpen->CodecConfig.ulEncoderPort != cOCT6100_NO_ENCODING && + f_pTempChanOpen->CodecConfig.ulEncodingRate != cOCT6100_G711_64KBPS ) + return cOCT6100_ERR_CHANNEL_ENCODING_RATE; + + if ( f_pTempChanOpen->CodecConfig.ulDecoderPort != cOCT6100_NO_DECODING && + f_pTempChanOpen->CodecConfig.ulDecodingRate != cOCT6100_G711_64KBPS ) + return cOCT6100_ERR_CHANNEL_DECODING_RATE; + } + + } + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiModifyChannelResources + +Description: Reserves any new resources needed for the channel +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelModify Pointer to echo cancellation channel configuration structure. +f_usChanIndex Allocated entry in ECHO channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiModifyChannelResources +UINT32 Oct6100ApiModifyChannelResources( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChannelModify, + IN UINT16 f_usChanIndex, + OUT PUINT16 f_pusNewRinTsstIndex, + OUT PUINT16 f_pusNewSinTsstIndex, + OUT PUINT16 f_pusNewRoutTsstIndex, + OUT PUINT16 f_pusNewSoutTsstIndex ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + + tPOCT6100_API_CHANNEL_TDM pApiTdmConf; + tPOCT6100_CHANNEL_MODIFY_TDM pModifyTdmConf; + + UINT32 ulResult = cOCT6100_ERR_OK; + UINT32 ulTempVar = cOCT6100_ERR_OK; + UINT32 ulFreeMixerEventCnt; + + BOOL fRinReleased = FALSE; + BOOL fSinReleased = FALSE; + BOOL fRoutReleased = FALSE; + BOOL fSoutReleased = FALSE; + + BOOL fRinReserved = FALSE; + BOOL fSinReserved = FALSE; + BOOL fRoutReserved = FALSE; + BOOL fSoutReserved = FALSE; + + BOOL fReserveRin = FALSE; + BOOL fReserveSin = FALSE; + BOOL fReserveRout = FALSE; + BOOL fReserveSout = FALSE; + + BOOL fRinRoutConversionMemReserved = FALSE; + BOOL fSinSoutConversionMemReserved = FALSE; + + + UINT32 ulRinNumTssts = 1; + UINT32 ulSinNumTssts = 1; + UINT32 ulRoutNumTssts = 1; + UINT32 ulSoutNumTssts = 1; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain local pointer to the TDM configuration structure of the tPOCT6100_CHANNEL_MODIFY structure. */ + pModifyTdmConf = &f_pChannelModify->TdmConfig; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ) + + /* Obtain local pointer to the TDM configuration structure of the tPOCT6100_API_CHANNEL structure. */ + pApiTdmConf = &pChanEntry->TdmConfig; + + /*===============================================================================*/ + /* Modify TSST resources if required.*/ + if ( f_pChannelModify->fTdmConfigModified == TRUE ) + { + /* First release any entry that need to be released.*/ + if ( ( pModifyTdmConf->ulRinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + || ( pModifyTdmConf->ulRinNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + ) + { + if ( pChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Release the previously reserved entry.*/ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pChanEntry->TdmConfig.usRinTimeslot, + pChanEntry->TdmConfig.usRinStream, + pChanEntry->TdmConfig.byRinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fRinReleased = TRUE; + } + } + + fReserveRin = TRUE; + } + + /* Release SIN port.*/ + if ( ( ulResult == cOCT6100_ERR_OK ) + && ( ( pModifyTdmConf->ulSinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + || ( pModifyTdmConf->ulSinNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + ) ) + { + if ( pChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Release the previously reserved entry.*/ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pChanEntry->TdmConfig.usSinTimeslot, + pChanEntry->TdmConfig.usSinStream, + pChanEntry->TdmConfig.bySinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fSinReleased = TRUE; + } + } + + fReserveSin = TRUE; + } + + /* Release ROUT port.*/ + if ( ( ulResult == cOCT6100_ERR_OK ) + && ( ( pModifyTdmConf->ulRoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + || ( pModifyTdmConf->ulRoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + ) ) + { + if ( pChanEntry->usRoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Release the previously reserved entry.*/ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pChanEntry->TdmConfig.usRoutTimeslot, + pChanEntry->TdmConfig.usRoutStream, + pChanEntry->TdmConfig.byRoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fRoutReleased = TRUE; + } + } + + fReserveRout = TRUE; + } + + /* Release the SOUT port.*/ + if ( ( ulResult == cOCT6100_ERR_OK ) + && ( ( pModifyTdmConf->ulSoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + || ( pModifyTdmConf->ulSoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + ) ) + { + if ( pChanEntry->usSoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Release the previously reserved entry.*/ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pChanEntry->TdmConfig.usSoutTimeslot, + pChanEntry->TdmConfig.usSoutStream, + pChanEntry->TdmConfig.bySoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fSoutReleased = TRUE; + } + } + + fReserveSout = TRUE; + } + + /* Now reserve any new entry required.*/ + + /* Modify RIN port.*/ + if ( ( fReserveRin == TRUE ) && ( ulResult == cOCT6100_ERR_OK ) ) + { + if ( pModifyTdmConf->ulRinTimeslot != cOCT6100_UNASSIGNED ) + { + /* Check what number of TSSTs should be reserved this time. */ + if ( pModifyTdmConf->ulRinNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + ulRinNumTssts = pApiTdmConf->byRinNumTssts; + } + else /* if ( pModifyTdmConf->ulRinNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* New number of TSSTs. */ + ulRinNumTssts = pModifyTdmConf->ulRinNumTssts; + } + + if ( pModifyTdmConf->ulRinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Reserve the new number of TSSTs. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pApiTdmConf->usRinTimeslot, + pApiTdmConf->usRinStream, + ulRinNumTssts, + cOCT6100_INPUT_TSST, + f_pusNewRinTsstIndex, + NULL ); + } + else /* if ( pModifyTdmConf->ulRinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* Reserve the new TSST.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pModifyTdmConf->ulRinTimeslot, + pModifyTdmConf->ulRinStream, + ulRinNumTssts, + cOCT6100_INPUT_TSST, + f_pusNewRinTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fRinReserved = TRUE; + } + } + } + else + { + *f_pusNewRinTsstIndex = cOCT6100_INVALID_INDEX; + } + } + else + { + *f_pusNewRinTsstIndex = cOCT6100_INVALID_INDEX; + } + + /* Modify SIN port.*/ + if ( ( fReserveSin == TRUE ) && ( ulResult == cOCT6100_ERR_OK ) ) + { + if ( pModifyTdmConf->ulSinTimeslot != cOCT6100_UNASSIGNED ) + { + /* Check what number of TSSTs should be reserved this time. */ + if ( pModifyTdmConf->ulSinNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + ulSinNumTssts = pApiTdmConf->bySinNumTssts; + } + else /* if ( pModifyTdmConf->ulSinNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* New number of TSSTs. */ + ulSinNumTssts = pModifyTdmConf->ulSinNumTssts; + } + + if ( pModifyTdmConf->ulSinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Reserve the new number of TSSTs. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pApiTdmConf->usSinTimeslot, + pApiTdmConf->usSinStream, + ulSinNumTssts, + cOCT6100_INPUT_TSST, + f_pusNewSinTsstIndex, + NULL ); + } + else /* if ( pModifyTdmConf->ulSinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* Reserve the new TSST.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pModifyTdmConf->ulSinTimeslot, + pModifyTdmConf->ulSinStream, + ulSinNumTssts, + cOCT6100_INPUT_TSST, + f_pusNewSinTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fSinReserved = TRUE; + } + } + } + else + { + *f_pusNewSinTsstIndex = cOCT6100_INVALID_INDEX; + } + } + else + { + *f_pusNewSinTsstIndex = cOCT6100_INVALID_INDEX; + } + + /* Modify ROUT port.*/ + if ( ( fReserveRout == TRUE ) && ( ulResult == cOCT6100_ERR_OK ) ) + { + if ( pModifyTdmConf->ulRoutTimeslot != cOCT6100_UNASSIGNED ) + { + /* Check what number of TSSTs should be reserved this time. */ + if ( pModifyTdmConf->ulRoutNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + ulRoutNumTssts = pApiTdmConf->byRoutNumTssts; + } + else /* if ( pModifyTdmConf->ulRoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* New number of TSSTs. */ + ulRoutNumTssts = pModifyTdmConf->ulRoutNumTssts; + } + + if ( pModifyTdmConf->ulRoutTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Reserve the new number of TSSTs. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pApiTdmConf->usRoutTimeslot, + pApiTdmConf->usRoutStream, + ulRoutNumTssts, + cOCT6100_OUTPUT_TSST, + f_pusNewRoutTsstIndex, + NULL ); + } + else /* if ( pModifyTdmConf->ulRoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* Reserve the new TSST.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pModifyTdmConf->ulRoutTimeslot, + pModifyTdmConf->ulRoutStream, + ulRoutNumTssts, + cOCT6100_OUTPUT_TSST, + f_pusNewRoutTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fRoutReserved = TRUE; + } + } + } + else + { + *f_pusNewRoutTsstIndex = cOCT6100_INVALID_INDEX; + } + } + else + { + *f_pusNewRoutTsstIndex = cOCT6100_INVALID_INDEX; + } + + /* Modify SOUT port.*/ + if ( ( fReserveSout == TRUE ) && ( ulResult == cOCT6100_ERR_OK ) ) + { + if ( pModifyTdmConf->ulSoutTimeslot != cOCT6100_UNASSIGNED ) + { + /* Check what number of TSSTs should be reserved this time. */ + if ( pModifyTdmConf->ulSoutNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + ulSoutNumTssts = pApiTdmConf->bySoutNumTssts; + } + else /* if ( pModifyTdmConf->ulSoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* New number of TSSTs. */ + ulSoutNumTssts = pModifyTdmConf->ulSoutNumTssts; + } + + if ( pModifyTdmConf->ulSoutTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Reserve the new number of TSSTs. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pApiTdmConf->usSoutTimeslot, + pApiTdmConf->usSoutStream, + ulSoutNumTssts, + cOCT6100_OUTPUT_TSST, + f_pusNewSoutTsstIndex, + NULL ); + } + else /* if ( pModifyTdmConf->ulSoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* Reserve the new TSST.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pModifyTdmConf->ulSoutTimeslot, + pModifyTdmConf->ulSoutStream, + ulSoutNumTssts, + cOCT6100_OUTPUT_TSST, + f_pusNewSoutTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fSoutReserved = TRUE; + } + } + } + else + { + *f_pusNewSoutTsstIndex = cOCT6100_INVALID_INDEX; + } + } + else + { + *f_pusNewSoutTsstIndex = cOCT6100_INVALID_INDEX; + } + + + } + + if ( f_pChannelModify->fCodecConfigModified == TRUE ) + { + if ( ulResult == cOCT6100_ERR_OK && + pChanEntry->usRinRoutConversionMemIndex == cOCT6100_INVALID_INDEX && + ( f_pChannelModify->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT || + f_pChannelModify->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) ) + { + /* Reserve an ADPCM memory block.*/ + ulResult = Oct6100ApiReserveConversionMemEntry( f_pApiInstance, &pChanEntry->usRinRoutConversionMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fRinRoutConversionMemReserved = TRUE; + } + } + + if ( ulResult == cOCT6100_ERR_OK && + pChanEntry->usSinSoutConversionMemIndex == cOCT6100_INVALID_INDEX && + ( f_pChannelModify->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT || + f_pChannelModify->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN ) ) + { + /* Reserve an ADPCM memory block.*/ + ulResult = Oct6100ApiReserveConversionMemEntry( f_pApiInstance, &pChanEntry->usSinSoutConversionMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fSinSoutConversionMemReserved = TRUE; + } + } + } + + + /*===============================================================================*/ + /* Check if there are a couple of mixer events available for us. */ + + if ( ulResult == cOCT6100_ERR_OK ) + { + UINT32 ulMixerEventCntNeeded = 0; + + /* Calculate how many mixer events are needed. */ + if ( pChanEntry->usBridgeIndex == cOCT6100_INVALID_INDEX ) + { + /* If the channel is in bidir mode, do not create the Rin silence event!!! */ + if ( pChanEntry->fBiDirChannel == FALSE ) + { + if ( ( *f_pusNewRinTsstIndex == cOCT6100_INVALID_INDEX ) + && ( pChanEntry->usRinSilenceEventIndex == cOCT6100_INVALID_INDEX ) ) + ulMixerEventCntNeeded++; + } + } + + if ( ( *f_pusNewSinTsstIndex == cOCT6100_INVALID_INDEX ) + && ( pChanEntry->usSinSilenceEventIndex == cOCT6100_INVALID_INDEX ) ) + { + ulMixerEventCntNeeded++; + } + + /* If at least 1 mixer event is needed, check if those are available. */ + if ( ulMixerEventCntNeeded != 0 ) + { + ulResult = Oct6100ApiGetFreeMixerEventCnt( f_pApiInstance, &ulFreeMixerEventCnt ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* The API might need more mixer events if the ports have to be muted. */ + /* Check if these are available. */ + if ( ulFreeMixerEventCnt < ulMixerEventCntNeeded ) + { + ulResult = cOCT6100_ERR_CHANNEL_OUT_OF_MIXER_EVENTS; + } + } + } + } + + /*===============================================================================*/ + + /* Verify if an error occured. */ + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Release any resources newly reserved.*/ + if ( fRinReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pModifyTdmConf->ulRinTimeslot, + pModifyTdmConf->ulRinStream, + ulRinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* For the SIN port.*/ + if ( fSinReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pModifyTdmConf->ulSinTimeslot, + pModifyTdmConf->ulSinStream, + ulSinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* For the ROUT port.*/ + if ( fRoutReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pModifyTdmConf->ulRoutTimeslot, + pModifyTdmConf->ulRoutStream, + ulRoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* For the SOUT port.*/ + if ( fSoutReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pModifyTdmConf->ulSoutTimeslot, + pModifyTdmConf->ulSoutStream, + ulSoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* Now make sure any resources released gets reserved back again.*/ + + /* For the RIN port.*/ + if ( fRinReleased == TRUE ) + { + /* Reserve the new TSST.*/ + ulTempVar = Oct6100ApiReserveTsst( f_pApiInstance, + pChanEntry->TdmConfig.usRinTimeslot, + pChanEntry->TdmConfig.usRinStream, + pChanEntry->TdmConfig.byRinNumTssts, + cOCT6100_INPUT_TSST, + &pChanEntry->usRinTsstIndex, + NULL ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* For the SIN port.*/ + if ( fSinReleased == TRUE ) + { + /* Reserve the new TSST.*/ + ulTempVar = Oct6100ApiReserveTsst( f_pApiInstance, + pChanEntry->TdmConfig.usSinTimeslot, + pChanEntry->TdmConfig.usSinStream, + pChanEntry->TdmConfig.bySinNumTssts, + cOCT6100_INPUT_TSST, + &pChanEntry->usSinTsstIndex, + NULL ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* For the ROUT port.*/ + if ( fRoutReleased == TRUE ) + { + /* Reserve the new TSST.*/ + ulTempVar = Oct6100ApiReserveTsst( f_pApiInstance, + pChanEntry->TdmConfig.usRoutTimeslot, + pChanEntry->TdmConfig.usRoutStream, + pChanEntry->TdmConfig.byRoutNumTssts, + cOCT6100_OUTPUT_TSST, + &pChanEntry->usRoutTsstIndex, + NULL ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* For the SOUT port.*/ + if ( fSoutReleased == TRUE ) + { + /* Reserve the new TSST.*/ + ulTempVar = Oct6100ApiReserveTsst( f_pApiInstance, + pChanEntry->TdmConfig.usSoutTimeslot, + pChanEntry->TdmConfig.usSoutStream, + pChanEntry->TdmConfig.bySoutNumTssts, + cOCT6100_OUTPUT_TSST, + &pChanEntry->usSoutTsstIndex, + NULL ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* Release the conversion memories if they were reserved.*/ + if ( fRinRoutConversionMemReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, + pChanEntry->usRinRoutConversionMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fSinSoutConversionMemReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, + pChanEntry->usSinSoutConversionMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* Now return the error.*/ + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiModifyChannelStructs + +Description: Performs all the required structure writes to configure the + echo cancellation channel based on the new modifications. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelModify Pointer to echo cancellation channel configuration structure. +f_pChannelOpen Pointer to a structure used to store the multiple resources indexes. +f_usChanIndex Index of the channel within the API's channel list. +f_usNewPhasingTsstIndex Index of the new phasing TSST. +f_pfSinSoutCodecActive Pointer to the state of the SIN/SOUT codec. +f_pfRinRoutCodecActive Pointer to the state of the RIN/ROUT codec. +f_usNewRinTsstIndex New RIN TSST memory index. +f_usNewSinTsstIndex New SIN TSST memory index. +f_usNewRoutTsstIndex New ROUT TSST memory index. +f_usNewSoutTsstIndex New SOUT TSST memory index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiModifyChannelStructs +UINT32 Oct6100ApiModifyChannelStructs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChannelModify, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usNewPhasingTsstIndex, + OUT PUINT8 f_pfSinSoutCodecActive, + OUT PUINT8 f_pfRinRoutCodecActive, + IN UINT16 f_usNewRinTsstIndex, + IN UINT16 f_usNewSinTsstIndex, + IN UINT16 f_usNewRoutTsstIndex, + IN UINT16 f_usNewSoutTsstIndex ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_WRITE_PARAMS WriteParams; + tPOCT6100_API_CHANNEL_CODEC pApiCodecConf; + tPOCT6100_API_CHANNEL_TDM pApiTdmConf; + + UINT32 ulResult; + UINT16 usReadData; + + UINT16 usSinTsstIndex; + UINT16 usRinTsstIndex; + + UINT32 ulToneConfIndex; + BOOL fClearPlayoutPointers = FALSE; + + + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ) + + /* Obtain local pointer to the configuration structures of the tPOCT6100_API_CHANNEL structure. */ + pApiCodecConf = &pChanEntry->CodecConfig; + pApiTdmConf = &pChanEntry->TdmConfig; + + /*=======================================================================*/ + /* Init the RIN and SIN TSST index */ + + usRinTsstIndex = pChanEntry->usRinTsstIndex; + usSinTsstIndex = pChanEntry->usSinTsstIndex; + + + /*==============================================================================*/ + /* Clear the TSST that will be release.*/ + + if ( f_pChannelModify->fTdmConfigModified == TRUE ) + { + /* Modify RIN port.*/ + if ( f_pChannelModify->TdmConfig.ulRinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( pChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Clear the previous entry */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (pChanEntry->usRinTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Modify SIN port.*/ + if ( f_pChannelModify->TdmConfig.ulSinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( pChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Clear the previous entry */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (pChanEntry->usSinTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Modify ROUT port.*/ + if ( f_pChannelModify->TdmConfig.ulRoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( pChanEntry->usRoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Clear the previous entry */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (pChanEntry->usRoutTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Modify SOUT port.*/ + if ( f_pChannelModify->TdmConfig.ulSoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING) + { + if ( pChanEntry->usSoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Clear the previous entry */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (pChanEntry->usSoutTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Now, Configure the Tsst control memory.*/ + + if ( f_pChannelModify->fTdmConfigModified == TRUE ) + { + /* Modify RIN port.*/ + if ( f_pChannelModify->TdmConfig.ulRinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + usRinTsstIndex = f_usNewRinTsstIndex; + + if ( f_usNewRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + if ( pChanEntry->usExtraRinTsiMemIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_usNewRinTsstIndex, + pChanEntry->usExtraRinTsiMemIndex, + f_pChannelOpen->TdmConfig.ulRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_usNewRinTsstIndex, + pChanEntry->usRinRoutTsiMemIndex, + f_pChannelOpen->TdmConfig.ulRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + if ( f_pChannelModify->TdmConfig.ulRinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulRinPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( pChanEntry->usExtraRinTsiMemIndex != cOCT6100_INVALID_INDEX ) + { + if ( pChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pChanEntry->usRinTsstIndex, + pChanEntry->usExtraRinTsiMemIndex, + f_pChannelOpen->TdmConfig.ulRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else + { + if ( pChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pChanEntry->usRinTsstIndex, + pChanEntry->usRinRoutTsiMemIndex, + f_pChannelOpen->TdmConfig.ulRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Modify SIN port.*/ + if ( f_pChannelModify->TdmConfig.ulSinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + usSinTsstIndex = f_usNewSinTsstIndex; + + if ( f_usNewSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + if ( pChanEntry->usExtraSinTsiMemIndex != cOCT6100_INVALID_INDEX ) + { + /* Write the new entry now.*/ + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_usNewSinTsstIndex, + pChanEntry->usExtraSinTsiMemIndex, + f_pChannelOpen->TdmConfig.ulSinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + /* Write the new entry now.*/ + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_usNewSinTsstIndex, + pChanEntry->usSinSoutTsiMemIndex, + f_pChannelOpen->TdmConfig.ulSinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + if ( f_pChannelModify->TdmConfig.ulSinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulSinPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( pChanEntry->usExtraSinTsiMemIndex != cOCT6100_INVALID_INDEX ) + { + if ( pChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pChanEntry->usSinTsstIndex , + pChanEntry->usExtraSinTsiMemIndex, + f_pChannelOpen->TdmConfig.ulSinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else + { + if ( pChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pChanEntry->usSinTsstIndex , + pChanEntry->usSinSoutTsiMemIndex, + f_pChannelOpen->TdmConfig.ulSinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Modify ROUT port.*/ + if ( ( f_pChannelModify->TdmConfig.ulRoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + || ( f_pChannelModify->TdmConfig.ulRoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + ) + { + if ( f_usNewRoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + if ( f_pChannelModify->TdmConfig.ulRoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* If this output port is not muted. */ + if ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_ROUT ) == 0x0 ) + { + /* Write the new entry now.*/ + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_usNewRoutTsstIndex, + pApiCodecConf->byAdpcmNibblePosition, + f_pChannelModify->TdmConfig.ulRoutNumTssts, + pChanEntry->usRinRoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else + { + /* If this output port is not muted. */ + if ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_ROUT ) == 0x0 ) + { + /* Write the new entry now.*/ + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_usNewRoutTsstIndex, + pApiCodecConf->byAdpcmNibblePosition, + pApiTdmConf->byRoutNumTssts, + pChanEntry->usRinRoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + } + + /* Modify SOUT port.*/ + if ( ( f_pChannelModify->TdmConfig.ulSoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + || ( f_pChannelModify->TdmConfig.ulSoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + ) + { + if ( f_usNewSoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + if ( f_pChannelModify->TdmConfig.ulSoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* If this output port is not muted. */ + if ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SOUT ) == 0x0 ) + { + /* Write the new entry now.*/ + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_usNewSoutTsstIndex, + pApiCodecConf->byAdpcmNibblePosition, + f_pChannelModify->TdmConfig.ulSoutNumTssts, + pChanEntry->usSinSoutTsiMemIndex ); + + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else + { + /* If this output port is not muted. */ + if ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SOUT ) == 0x0 ) + { + /* Write the new entry now.*/ + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_usNewSoutTsstIndex, + pApiCodecConf->byAdpcmNibblePosition, + pApiTdmConf->bySoutNumTssts, + pChanEntry->usSinSoutTsiMemIndex ); + + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + } + + + + } + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Modify the Encoder/Decoder memory if required.*/ + + if ( f_pChannelModify->fCodecConfigModified == TRUE ) + { + UINT32 ulCompType = 0; + UINT16 usTempTsiMemIndex; + UINT16 usDecoderMemIndex; + UINT16 usEncoderMemIndex; + UINT32 ulPcmLaw; + UINT16 usPhasingIndex; + BOOL fModifyAdpcmMem = TRUE; + + /*==============================================================================*/ + /* Reprogram the Decoder memory.*/ + + if ( pChanEntry->CodecConfig.byDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + usDecoderMemIndex = pChanEntry->usRinRoutConversionMemIndex; + } + else + { + usDecoderMemIndex = pChanEntry->usSinSoutConversionMemIndex; + } + + if ( pChanEntry->CodecConfig.byEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + usEncoderMemIndex = pChanEntry->usRinRoutConversionMemIndex; + } + else + { + usEncoderMemIndex = pChanEntry->usSinSoutConversionMemIndex; + } + + if ( usDecoderMemIndex != cOCT6100_INVALID_INDEX ) + { + switch( f_pChannelOpen->CodecConfig.ulDecodingRate ) + { + case cOCT6100_G711_64KBPS: + ulCompType = 0x8; + + if ( f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + if ( f_pChannelOpen->TdmConfig.ulRinPcmLaw == f_pChannelOpen->TdmConfig.ulRoutPcmLaw ) + fModifyAdpcmMem = FALSE; + + /* Check if both ports are assigned. If not, no law conversion needed here.. */ + if ( ( f_pChannelOpen->TdmConfig.ulRinStream == cOCT6100_UNASSIGNED ) + || ( f_pChannelOpen->TdmConfig.ulRoutStream == cOCT6100_UNASSIGNED ) ) + fModifyAdpcmMem = FALSE; + } + else /* f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN */ + { + if ( f_pChannelOpen->TdmConfig.ulSinPcmLaw == f_pChannelOpen->TdmConfig.ulSoutPcmLaw ) + fModifyAdpcmMem = FALSE; + + /* Check if both ports are assigned. If not, no law conversion needed here.. */ + if ( ( f_pChannelOpen->TdmConfig.ulSinStream == cOCT6100_UNASSIGNED ) + || ( f_pChannelOpen->TdmConfig.ulSoutStream == cOCT6100_UNASSIGNED ) ) + fModifyAdpcmMem = FALSE; + } + + break; + case cOCT6100_G726_40KBPS: + ulCompType = 0x3; + break; + + case cOCT6100_G726_32KBPS: + ulCompType = 0x2; + break; + + case cOCT6100_G726_24KBPS: + ulCompType = 0x1; + break; + + case cOCT6100_G726_16KBPS: + ulCompType = 0x0; + break; + + case cOCT6100_G727_2C_ENCODED: + ulCompType = 0x4; + break; + + case cOCT6100_G727_3C_ENCODED: + ulCompType = 0x5; + break; + + case cOCT6100_G727_4C_ENCODED: + ulCompType = 0x6; + break; + + case cOCT6100_G726_ENCODED: + ulCompType = 0x9; + break; + + case cOCT6100_G711_G726_ENCODED: + ulCompType = 0xA; + break; + + case cOCT6100_G711_G727_2C_ENCODED: + ulCompType = 0xC; + break; + + case cOCT6100_G711_G727_3C_ENCODED: + ulCompType = 0xD; + break; + + case cOCT6100_G711_G727_4C_ENCODED: + ulCompType = 0xE; + break; + + default: + return cOCT6100_ERR_FATAL_D6; + } + + if ( fModifyAdpcmMem == TRUE ) + { + /* Set the chariot memory based on the selected port.*/ + if ( f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + usTempTsiMemIndex = pChanEntry->usRinRoutTsiMemIndex; + ulPcmLaw = f_pChannelOpen->TdmConfig.ulRoutPcmLaw; /* Set the law for later use */ + + /* Flag the entry as active.*/ + *f_pfRinRoutCodecActive = TRUE; + } + else /* f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN */ + { + usTempTsiMemIndex = pChanEntry->usSinSoutTsiMemIndex; + ulPcmLaw = f_pChannelOpen->TdmConfig.ulSoutPcmLaw; /* Set the law for later use */ + + /* Flag the entry as active.*/ + *f_pfSinSoutCodecActive = TRUE; + } + + ulResult = Oct6100ApiWriteDecoderMemory( f_pApiInstance, + usDecoderMemIndex, + ulCompType, + usTempTsiMemIndex, + ulPcmLaw, + pApiCodecConf->byAdpcmNibblePosition ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + ulResult = Oct6100ApiClearConversionMemory( f_pApiInstance, + usDecoderMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Flag the entry as deactivated.*/ + if ( f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + *f_pfRinRoutCodecActive = FALSE; + } + else + { + *f_pfSinSoutCodecActive = FALSE; + } + } + } + + /*==============================================================================*/ + + + + + /*==============================================================================*/ + /* Reprogram the Encoder memory.*/ + + if ( usEncoderMemIndex != cOCT6100_INVALID_INDEX ) + { + + fModifyAdpcmMem = TRUE; + + /* Set the chariot memory based on the selected port.*/ + if ( f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + usTempTsiMemIndex = pChanEntry->usRinRoutTsiMemIndex; + ulPcmLaw = f_pChannelOpen->TdmConfig.ulRoutPcmLaw; /* Set the law for later use */ + } + else /* f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + usTempTsiMemIndex = pChanEntry->usSinSoutTsiMemIndex; + ulPcmLaw = f_pChannelOpen->TdmConfig.ulSoutPcmLaw; /* Set the law for later use */ + } + + /* Set the phasing index .*/ + if ( f_usNewPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + usPhasingIndex = f_usNewPhasingTsstIndex; + else + usPhasingIndex = pChanEntry->usPhasingTsstIndex; + + switch( f_pChannelOpen->CodecConfig.ulEncodingRate ) + { + case cOCT6100_G711_64KBPS: + if ( ulPcmLaw == cOCT6100_PCM_U_LAW ) + ulCompType = 0x4; + else /* ulPcmLaw == cOCT6100_PCM_A_LAW */ + ulCompType = 0x5; + + if ( f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + if ( f_pChannelOpen->TdmConfig.ulRinPcmLaw == f_pChannelOpen->TdmConfig.ulRoutPcmLaw ) + fModifyAdpcmMem = FALSE; + + /* Check if both ports are assigned. If not, no law conversion needed here.. */ + if ( ( f_pChannelOpen->TdmConfig.ulRinStream == cOCT6100_UNASSIGNED ) + || ( f_pChannelOpen->TdmConfig.ulRoutStream == cOCT6100_UNASSIGNED ) ) + fModifyAdpcmMem = FALSE; + } + else /* f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + if ( f_pChannelOpen->TdmConfig.ulSinPcmLaw == f_pChannelOpen->TdmConfig.ulSoutPcmLaw ) + fModifyAdpcmMem = FALSE; + + /* Check if both ports are assigned. If not, no law conversion needed here.. */ + if ( ( f_pChannelOpen->TdmConfig.ulSinStream == cOCT6100_UNASSIGNED ) + || ( f_pChannelOpen->TdmConfig.ulSoutStream == cOCT6100_UNASSIGNED ) ) + fModifyAdpcmMem = FALSE; + } + break; + case cOCT6100_G726_40KBPS: + ulCompType = 0x3; + break; + + case cOCT6100_G726_32KBPS: + ulCompType = 0x2; + break; + + case cOCT6100_G726_24KBPS: + ulCompType = 0x1; + break; + + case cOCT6100_G726_16KBPS: + ulCompType = 0x0; + break; + + case cOCT6100_G727_40KBPS_4_1: + ulCompType = 0xD; + break; + + case cOCT6100_G727_40KBPS_3_2: + ulCompType = 0xA; + break; + + case cOCT6100_G727_40KBPS_2_3: + ulCompType = 0x6; + break; + + case cOCT6100_G727_32KBPS_4_0: + ulCompType = 0xE; + break; + + case cOCT6100_G727_32KBPS_3_1: + ulCompType = 0xB; + break; + + case cOCT6100_G727_32KBPS_2_2: + ulCompType = 0x7; + break; + + case cOCT6100_G727_24KBPS_3_0: + ulCompType = 0xC; + break; + + case cOCT6100_G727_24KBPS_2_1: + ulCompType = 0x8; + break; + + case cOCT6100_G727_16KBPS_2_0: + ulCompType = 0x9; + break; + + default: + return cOCT6100_ERR_FATAL_D7; + } + + if ( fModifyAdpcmMem == TRUE ) + { + if ( f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + *f_pfRinRoutCodecActive = TRUE; + } + else /* f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + *f_pfSinSoutCodecActive = TRUE; + } + + ulResult = Oct6100ApiWriteEncoderMemory( f_pApiInstance, + usEncoderMemIndex, + ulCompType, + usTempTsiMemIndex, + f_pChannelOpen->CodecConfig.fEnableSilenceSuppression, + pApiCodecConf->byAdpcmNibblePosition, + usPhasingIndex, + f_pChannelOpen->CodecConfig.ulPhasingType, + f_pChannelOpen->CodecConfig.ulPhase ); + + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + ulResult = Oct6100ApiClearConversionMemory( f_pApiInstance, + usEncoderMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + *f_pfRinRoutCodecActive = FALSE; + } + else /* f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + *f_pfSinSoutCodecActive = FALSE; + } + } + } + + /*==============================================================================*/ + } + + + + + /*==============================================================================*/ + /* Modify the VQE parameter if required.*/ + + if ( ( f_pChannelModify->fVqeConfigModified == TRUE ) + || ( (UINT8)f_pChannelOpen->ulEchoOperationMode != pChanEntry->byEchoOperationMode ) + || ( f_pChannelOpen->fEnableToneDisabler != pChanEntry->fEnableToneDisabler ) ) + { + ulResult = Oct6100ApiWriteVqeMemory( f_pApiInstance, + &f_pChannelOpen->VqeConfig, + f_pChannelOpen, + f_usChanIndex, + pChanEntry->usEchoMemIndex, + FALSE, + TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*==============================================================================*/ + /* Modify the Echo memory if required.*/ + if ( f_pChannelModify->fEnableToneDisabler != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->ulEchoOperationMode != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->TdmConfig.ulRinPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->TdmConfig.ulSinPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->TdmConfig.ulRoutPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->TdmConfig.ulSoutPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + ulResult = Oct6100ApiWriteEchoMemory( f_pApiInstance, + &f_pChannelOpen->TdmConfig, + f_pChannelOpen, + pChanEntry->usEchoMemIndex, + pChanEntry->usRinRoutTsiMemIndex, + pChanEntry->usSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Synch all the buffer playout field if needed by echo operation mode. */ + /* Note that Oct6100ApiWriteVqeMemory does not clear the playout pointers */ + /* since the flag is set to FALSE. */ + if ( ( pSharedInfo->ImageInfo.fBufferPlayout == TRUE ) + && ( ( f_pChannelModify->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_HT_FREEZE ) + || ( f_pChannelModify->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_POWER_DOWN ) ) ) + { + /* Buffer playout must be stopped. */ + fClearPlayoutPointers = TRUE; + } + } + + /*==============================================================================*/ + /* Modify the Mixer events if law changes are requested. */ + + if ( pChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX && + f_pChannelModify->TdmConfig.ulSinPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + ReadParams.ulReadAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pChanEntry->usSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Modify the value according to the new law.*/ + if ( f_pChannelModify->TdmConfig.ulSinPcmLaw == cOCT6100_PCM_A_LAW ) + WriteParams.usWriteData = (UINT16)( usReadData | ( f_pChannelModify->TdmConfig.ulSinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET )); + else + WriteParams.usWriteData = (UINT16)( usReadData & (~( f_pChannelModify->TdmConfig.ulSinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET ))); + + /* Write back the new value.*/ + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pChanEntry->usSoutCopyEventIndex != cOCT6100_INVALID_INDEX && + f_pChannelModify->TdmConfig.ulSoutPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + ReadParams.ulReadAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pChanEntry->usSoutCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Modify the value according to the new law.*/ + if ( f_pChannelModify->TdmConfig.ulSoutPcmLaw == cOCT6100_PCM_A_LAW ) + WriteParams.usWriteData = (UINT16)( usReadData | ( f_pChannelModify->TdmConfig.ulSoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET )); + else + WriteParams.usWriteData = (UINT16)( usReadData & (~( f_pChannelModify->TdmConfig.ulSoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET ))); + + /* Write back the new value.*/ + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*==============================================================================*/ + /* Mute channel if required, this is done on a port basis */ + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, + f_usChanIndex, + usRinTsstIndex, + usSinTsstIndex, + TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + /* Completely disable tone detection? */ + if ( f_pChannelModify->fDisableToneDetection == TRUE ) + { + /* Check if tone detection has been enabled on this channel. */ + for (ulToneConfIndex = 0; ulToneConfIndex < ARRAY_SIZE(pChanEntry->aulToneConf); ulToneConfIndex++) + { + /* Check if some tone has been activated on this channel. */ + if ( pChanEntry->aulToneConf[ ulToneConfIndex ] != 0 ) + { + tOCT6100_TONE_DETECTION_DISABLE ToneDetectDisable; + + /* Call the default function to make sure all parameters are assigned default values. */ + ulResult = Oct6100ToneDetectionDisableDef( &ToneDetectDisable ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Form channel handle. */ + ToneDetectDisable.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | f_usChanIndex; + + /* Disable all tones activated on this channel. */ + ToneDetectDisable.fDisableAll = TRUE; + + /* Call tone detection serialized function. */ + ulResult = Oct6100ToneDetectionDisableSer( f_pApiInstance, &ToneDetectDisable ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Get out of the loop, tone detection has been disabled! */ + break; + } + } + } + + /* Hard-stop buffer playout? */ + if ( f_pChannelModify->fStopBufferPlayout == TRUE ) + { + /* Check if playout has been started on the Rout port. */ + if ( ( pChanEntry->fRinBufPlaying == TRUE ) || ( pChanEntry->fRinBufAdded == TRUE ) ) + { + tOCT6100_BUFFER_PLAYOUT_STOP PlayoutStop; + + /* Call the default function to make sure all parameters are assigned default values. */ + ulResult = Oct6100BufferPlayoutStopDef( &PlayoutStop ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Hard stop request. */ + PlayoutStop.fStopCleanly = FALSE; + + /* Form channel handle. */ + PlayoutStop.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | f_usChanIndex; + + /* For the Rout port. */ + PlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + + /* Call buffer playout stop serialized function. */ + ulResult = Oct6100BufferPlayoutStopSer( f_pApiInstance, &PlayoutStop ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + /* The chip might still be playing a last buffer. Make sure it hard-stops! */ + fClearPlayoutPointers = TRUE; + } + + /* Check if playout has been started on the Sout port. */ + if ( ( pChanEntry->fSoutBufPlaying == TRUE ) || ( pChanEntry->fSoutBufAdded == TRUE ) ) + { + tOCT6100_BUFFER_PLAYOUT_STOP PlayoutStop; + + /* Call the default function to make sure all parameters are assigned default values. */ + ulResult = Oct6100BufferPlayoutStopDef( &PlayoutStop ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Hard stop request. */ + PlayoutStop.fStopCleanly = FALSE; + + /* Form channel handle. */ + PlayoutStop.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | f_usChanIndex; + + /* For the Rout port. */ + PlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_SOUT; + + /* Call buffer playout stop serialized function. */ + ulResult = Oct6100BufferPlayoutStopSer( f_pApiInstance, &PlayoutStop ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + /* The chip might still be playing a last buffer. Make sure it hard-stops! */ + fClearPlayoutPointers = TRUE; + } + } + + /* Remove participant from bridge? */ + if ( f_pChannelModify->fRemoveConfBridgeParticipant == TRUE ) + { + /* Check if this channel is on a bridge. */ + if ( pChanEntry->usBridgeIndex != cOCT6100_INVALID_INDEX ) + { + /* Channel is on a bridge, remove it. */ + tOCT6100_CONF_BRIDGE_CHAN_REMOVE BridgeChanRemove; + + /* Call the default function to make sure all parameters are assigned default values. */ + ulResult = Oct6100ConfBridgeChanRemoveDef( &BridgeChanRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Form channel handle. */ + BridgeChanRemove.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | f_usChanIndex; + + /* Do not remove all channels, only the one specified. */ + BridgeChanRemove.fRemoveAll = FALSE; + + /* No need to assign conference bridge handle, the remove function will figure it out. */ + + /* Call conference bridge channel remove serialized function. */ + ulResult = Oct6100ConfBridgeChanRemoveSer( f_pApiInstance, &BridgeChanRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_DEPENDENCY ) + { + tPOCT6100_API_CHANNEL pTapChanEntry; + + /* Get a pointer to the tap channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTapChanEntry, pChanEntry->usTapChanIndex ) + + /* Form tap channel handle. */ + BridgeChanRemove.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pTapChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | pChanEntry->usTapChanIndex; + + ulResult = Oct6100ConfBridgeChanRemoveSer( f_pApiInstance, &BridgeChanRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Re-form original channel handle. */ + BridgeChanRemove.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | f_usChanIndex; + + ulResult = Oct6100ConfBridgeChanRemoveSer( f_pApiInstance, &BridgeChanRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + return ulResult; + } + } + } + } + + /* Remove all broadcast TSSTs? */ + if ( f_pChannelModify->fRemoveBroadcastTssts == TRUE ) + { + /* Check if broadcast TSSTs were used on the Rout port. */ + if ( pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry != cOCT6100_INVALID_INDEX ) + { + tOCT6100_CHANNEL_BROADCAST_TSST_REMOVE BroadcastTsstRemove; + + ulResult = Oct6100ChannelBroadcastTsstRemoveDef( &BroadcastTsstRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Form channel handle. */ + BroadcastTsstRemove.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | f_usChanIndex; + + /* Remove all broadcast TSSTs associated to the current channel. */ + BroadcastTsstRemove.fRemoveAll = TRUE; + + /* On the Rout port. */ + BroadcastTsstRemove.ulPort = cOCT6100_CHANNEL_PORT_ROUT; + + ulResult = Oct6100ChannelBroadcastTsstRemoveSer( f_pApiInstance, &BroadcastTsstRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + + /* Check if broadcast TSSTs were used on the Sout port. */ + if ( pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry != cOCT6100_INVALID_INDEX ) + { + tOCT6100_CHANNEL_BROADCAST_TSST_REMOVE BroadcastTsstRemove; + + ulResult = Oct6100ChannelBroadcastTsstRemoveDef( &BroadcastTsstRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Form channel handle. */ + BroadcastTsstRemove.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | f_usChanIndex; + + /* Remove all broadcast TSSTs associated to the current channel. */ + BroadcastTsstRemove.fRemoveAll = TRUE; + + /* On the Sout port. */ + BroadcastTsstRemove.ulPort = cOCT6100_CHANNEL_PORT_SOUT; + + ulResult = Oct6100ChannelBroadcastTsstRemoveSer( f_pApiInstance, &BroadcastTsstRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Check if have to make sure buffer playout is stopped. */ + if ( fClearPlayoutPointers == TRUE ) + { + tOCT6100_BUFFER_PLAYOUT_STOP BufferPlayoutStop; + + Oct6100BufferPlayoutStopDef( &BufferPlayoutStop ); + + BufferPlayoutStop.fStopCleanly = FALSE; + BufferPlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + + ulResult = Oct6100ApiInvalidateChanPlayoutStructs( + f_pApiInstance, + &BufferPlayoutStop, + f_usChanIndex, + pChanEntry->usEchoMemIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + BufferPlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_SOUT; + ulResult = Oct6100ApiInvalidateChanPlayoutStructs( + f_pApiInstance, + &BufferPlayoutStop, + f_usChanIndex, + pChanEntry->usEchoMemIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiModifyChannelEntry + +Description: Updates the channel structure in the ECHO channel list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelModify Pointer to echo cancellation channel modify structure. +f_pChannelOpen Pointer to echo cancellation channel configuration structure. +f_usChanIndex Index of the channel within the API's channel list. +f_usNewPhasingTsstIndex Index of the new phasing TSST. +f_fSinSoutCodecActive State of the SIN/SOUT codec. +f_fRinRoutCodecActive State of the RIN/ROUT codec. +f_usNewRinTsstIndex New RIN TSST memory index. +f_usNewSinTsstIndex New SIN TSST memory index. +f_usNewRoutTsstIndex New ROUT TSST memory index. +f_usNewSoutTsstIndex New SOUT TSST memory index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiModifyChannelEntry +UINT32 Oct6100ApiModifyChannelEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChannelModify, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usNewPhasingTsstIndex, + IN UINT8 f_fSinSoutCodecActive, + IN UINT8 f_fRinRoutCodecActive, + IN UINT16 f_usNewRinTsstIndex, + IN UINT16 f_usNewSinTsstIndex, + IN UINT16 f_usNewRoutTsstIndex, + IN UINT16 f_usNewSoutTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_CHANNEL_CODEC pApiCodecConf; + tPOCT6100_API_CHANNEL_TDM pApiTdmConf; + tPOCT6100_API_CHANNEL_VQE pApiVqeConf; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ) + + /* Obtain local pointer to the configuration structures of the tPOCT6100_API_CHANNEL structure. */ + pApiCodecConf = &pChanEntry->CodecConfig; + pApiTdmConf = &pChanEntry->TdmConfig; + pApiVqeConf = &pChanEntry->VqeConfig; + + /*=======================================================================*/ + /* Copy the channel's general configuration. */ + + pChanEntry->ulUserChanId = f_pChannelOpen->ulUserChanId; + pChanEntry->byEchoOperationMode = (UINT8)( f_pChannelOpen->ulEchoOperationMode & 0xFF ); + pChanEntry->fEnableToneDisabler = (UINT8)( f_pChannelOpen->fEnableToneDisabler & 0xFF ); + + /* Save the codec state.*/ + pChanEntry->fSinSoutCodecActive = (UINT8)( f_fSinSoutCodecActive & 0xFF ); + pChanEntry->fRinRoutCodecActive = (UINT8)( f_fRinRoutCodecActive & 0xFF ); + + /*=======================================================================*/ + /* Copy the channel's TDM configuration of all the modified fields. */ + + if ( f_pChannelModify->fTdmConfigModified == TRUE ) + { + pApiTdmConf->byRinPcmLaw = (UINT8)( f_pChannelOpen->TdmConfig.ulRinPcmLaw & 0xFF ); + pApiTdmConf->bySinPcmLaw = (UINT8)( f_pChannelOpen->TdmConfig.ulSinPcmLaw & 0xFF ); + pApiTdmConf->byRoutPcmLaw = (UINT8)( f_pChannelOpen->TdmConfig.ulRoutPcmLaw & 0xFF ); + pApiTdmConf->bySoutPcmLaw = (UINT8)( f_pChannelOpen->TdmConfig.ulSoutPcmLaw & 0xFF ); + + pApiTdmConf->byRinNumTssts = (UINT8)( f_pChannelOpen->TdmConfig.ulRinNumTssts & 0xFF ); + pApiTdmConf->bySinNumTssts = (UINT8)( f_pChannelOpen->TdmConfig.ulSinNumTssts & 0xFF ); + pApiTdmConf->byRoutNumTssts = (UINT8)( f_pChannelOpen->TdmConfig.ulRoutNumTssts & 0xFF ); + pApiTdmConf->bySoutNumTssts = (UINT8)( f_pChannelOpen->TdmConfig.ulSoutNumTssts & 0xFF ); + + if ( f_pChannelModify->TdmConfig.ulRinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( f_usNewRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + pApiTdmConf->usRinStream = (UINT16)( f_pChannelOpen->TdmConfig.ulRinStream & 0xFFFF ); + pApiTdmConf->usRinTimeslot = (UINT16)( f_pChannelOpen->TdmConfig.ulRinTimeslot & 0xFFFF ); + pChanEntry->usRinTsstIndex = f_usNewRinTsstIndex; + } + else /* f_ulNewRinTsstIndex != cOCT6100_INVALID_INDEX */ + { + pApiTdmConf->usRinStream = cOCT6100_UNASSIGNED; + pApiTdmConf->usRinTimeslot = cOCT6100_UNASSIGNED; + pChanEntry->usRinTsstIndex = cOCT6100_INVALID_INDEX; + } + } + + if ( f_pChannelModify->TdmConfig.ulSinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( f_usNewSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + pApiTdmConf->usSinStream = (UINT16)( f_pChannelOpen->TdmConfig.ulSinStream & 0xFFFF ); + pApiTdmConf->usSinTimeslot = (UINT16)( f_pChannelOpen->TdmConfig.ulSinTimeslot & 0xFFFF ); + pChanEntry->usSinTsstIndex = f_usNewSinTsstIndex; + } + else /* f_ulNewSinTsstIndex != cOCT6100_INVALID_INDEX */ + { + pApiTdmConf->usSinStream = cOCT6100_UNASSIGNED; + pApiTdmConf->usSinTimeslot = cOCT6100_UNASSIGNED; + pChanEntry->usSinTsstIndex = cOCT6100_INVALID_INDEX; + } + } + + if ( f_pChannelModify->TdmConfig.ulRoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( f_usNewRoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + pApiTdmConf->usRoutStream = (UINT16)( f_pChannelOpen->TdmConfig.ulRoutStream & 0xFFFF ); + pApiTdmConf->usRoutTimeslot = (UINT16)( f_pChannelOpen->TdmConfig.ulRoutTimeslot & 0xFFFF ); + pChanEntry->usRoutTsstIndex = f_usNewRoutTsstIndex; + } + else /* f_ulNewRoutTsstIndex != cOCT6100_INVALID_INDEX */ + { + pApiTdmConf->usRoutStream = cOCT6100_UNASSIGNED; + pApiTdmConf->usRoutTimeslot = cOCT6100_UNASSIGNED; + pChanEntry->usRoutTsstIndex = cOCT6100_INVALID_INDEX; + } + } + + if ( f_pChannelModify->TdmConfig.ulSoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( f_usNewSoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + pApiTdmConf->usSoutStream = (UINT16)( f_pChannelOpen->TdmConfig.ulSoutStream & 0xFFFF ); + pApiTdmConf->usSoutTimeslot = (UINT16)( f_pChannelOpen->TdmConfig.ulSoutTimeslot & 0xFFFF ); + pChanEntry->usSoutTsstIndex = f_usNewSoutTsstIndex; + } + else /* f_ulNewSoutTsstIndex != cOCT6100_INVALID_INDEX */ + { + pApiTdmConf->usSoutStream = cOCT6100_UNASSIGNED; + pApiTdmConf->usSoutTimeslot = cOCT6100_UNASSIGNED; + pChanEntry->usSoutTsstIndex = cOCT6100_INVALID_INDEX; + } + } + } + + /*=======================================================================*/ + /* Copy the channel's VQE configuration of all the modified fields. */ + + if ( f_pChannelModify->fVqeConfigModified == TRUE ) + { + pApiVqeConf->fEnableNlp = (UINT8)( f_pChannelOpen->VqeConfig.fEnableNlp & 0xFF ); + pApiVqeConf->byComfortNoiseMode = (UINT8)( f_pChannelOpen->VqeConfig.ulComfortNoiseMode & 0xFF ); + pApiVqeConf->fSinDcOffsetRemoval = (UINT8)( f_pChannelOpen->VqeConfig.fSinDcOffsetRemoval & 0xFF ); + pApiVqeConf->fRinDcOffsetRemoval = (UINT8)( f_pChannelOpen->VqeConfig.fRinDcOffsetRemoval & 0xFF ); + pApiVqeConf->fRinLevelControl = (UINT8)( f_pChannelOpen->VqeConfig.fRinLevelControl & 0xFF ); + pApiVqeConf->fSoutLevelControl = (UINT8)( f_pChannelOpen->VqeConfig.fSoutLevelControl & 0xFF ); + pApiVqeConf->fRinAutomaticLevelControl = (UINT8)( f_pChannelOpen->VqeConfig.fRinAutomaticLevelControl & 0xFF ); + pApiVqeConf->fSoutAutomaticLevelControl = (UINT8)( f_pChannelOpen->VqeConfig.fSoutAutomaticLevelControl & 0xFF ); + pApiVqeConf->fRinHighLevelCompensation = (UINT8)( f_pChannelOpen->VqeConfig.fRinHighLevelCompensation & 0xFF ); + + pApiVqeConf->fSoutAdaptiveNoiseReduction = (UINT8)( f_pChannelOpen->VqeConfig.fSoutAdaptiveNoiseReduction & 0xFF ); + pApiVqeConf->fSoutNoiseBleaching = (UINT8)( f_pChannelOpen->VqeConfig.fSoutNoiseBleaching & 0xFF ); + pApiVqeConf->fSoutConferencingNoiseReduction = (UINT8)( f_pChannelOpen->VqeConfig.fSoutConferencingNoiseReduction & 0xFF ); + pApiVqeConf->chRinLevelControlGainDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lRinLevelControlGainDb & 0xFF ); + pApiVqeConf->chSoutLevelControlGainDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lSoutLevelControlGainDb & 0xFF ); + pApiVqeConf->chRinAutomaticLevelControlTargetDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lRinAutomaticLevelControlTargetDb & 0xFF ); + pApiVqeConf->chSoutAutomaticLevelControlTargetDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lSoutAutomaticLevelControlTargetDb & 0xFF ); + pApiVqeConf->chRinHighLevelCompensationThresholdDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lRinHighLevelCompensationThresholdDb & 0xFF ); + pApiVqeConf->fEnableTailDisplacement = (UINT8)( f_pChannelOpen->VqeConfig.fEnableTailDisplacement & 0xFF ); + pApiVqeConf->usTailDisplacement = (UINT16)( f_pChannelOpen->VqeConfig.ulTailDisplacement & 0xFFFF ); + pApiVqeConf->usTailLength = (UINT16)( f_pChannelOpen->VqeConfig.ulTailLength & 0xFFFF ); + pApiVqeConf->fAcousticEcho = (UINT8)( f_pChannelOpen->VqeConfig.fAcousticEcho & 0xFF ); + pApiVqeConf->fDtmfToneRemoval = (UINT8)( f_pChannelOpen->VqeConfig.fDtmfToneRemoval & 0xFF ); + + pApiVqeConf->chDefaultErlDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lDefaultErlDb & 0xFF ); + pApiVqeConf->chAecDefaultErlDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lAecDefaultErlDb & 0xFF ); + pApiVqeConf->usAecTailLength = (UINT16)( f_pChannelOpen->VqeConfig.ulAecTailLength & 0xFFFF ); + pApiVqeConf->chAnrSnrEnhancementDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lAnrSnrEnhancementDb & 0xFF ); + pApiVqeConf->byAnrVoiceNoiseSegregation = (UINT8)( f_pChannelOpen->VqeConfig.ulAnrVoiceNoiseSegregation & 0xFF ); + pApiVqeConf->usToneDisablerVqeActivationDelay = (UINT16)( f_pChannelOpen->VqeConfig.ulToneDisablerVqeActivationDelay & 0xFFFF ); + pApiVqeConf->byNonLinearityBehaviorA = (UINT8)( f_pChannelOpen->VqeConfig.ulNonLinearityBehaviorA & 0xFF ); + pApiVqeConf->byNonLinearityBehaviorB = (UINT8)( f_pChannelOpen->VqeConfig.ulNonLinearityBehaviorB & 0xFF ); + pApiVqeConf->byDoubleTalkBehavior = (UINT8)( f_pChannelOpen->VqeConfig.ulDoubleTalkBehavior & 0xFF ); + pApiVqeConf->bySoutAutomaticListenerEnhancementGainDb = (UINT8)( f_pChannelOpen->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb & 0xFF ); + pApiVqeConf->bySoutNaturalListenerEnhancementGainDb = (UINT8)( f_pChannelOpen->VqeConfig.ulSoutNaturalListenerEnhancementGainDb & 0xFF ); + pApiVqeConf->fSoutNaturalListenerEnhancement = (UINT8)( f_pChannelOpen->VqeConfig.fSoutNaturalListenerEnhancement & 0xFF ); + pApiVqeConf->fRoutNoiseReduction = (UINT8)( f_pChannelOpen->VqeConfig.fRoutNoiseReduction & 0xFF ); + pApiVqeConf->chRoutNoiseReductionLevelGainDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lRoutNoiseReductionLevelGainDb & 0xFF ); + pApiVqeConf->fEnableMusicProtection = (UINT8)( f_pChannelOpen->VqeConfig.fEnableMusicProtection & 0xFF ); + pApiVqeConf->fIdleCodeDetection = (UINT8)( f_pChannelOpen->VqeConfig.fIdleCodeDetection & 0xFF ); + } + + /*=======================================================================*/ + /* Copy the channel's CODEC configuration of all the modified fields. */ + if ( f_pChannelModify->fCodecConfigModified == TRUE ) + { + pApiCodecConf->byAdpcmNibblePosition = (UINT8)( f_pChannelOpen->CodecConfig.ulAdpcmNibblePosition & 0xFF ); + pApiCodecConf->byEncoderPort = (UINT8)( f_pChannelOpen->CodecConfig.ulEncoderPort & 0xFF ); + pApiCodecConf->byEncodingRate = (UINT8)( f_pChannelOpen->CodecConfig.ulEncodingRate & 0xFF ); + pApiCodecConf->byDecoderPort = (UINT8)( f_pChannelOpen->CodecConfig.ulDecoderPort & 0xFF ); + pApiCodecConf->byDecodingRate = (UINT8)( f_pChannelOpen->CodecConfig.ulDecodingRate & 0xFF ); + pApiCodecConf->fEnableSilenceSuppression = (UINT8)( f_pChannelOpen->CodecConfig.fEnableSilenceSuppression & 0xFF ); + pApiCodecConf->byPhase = (UINT8)( f_pChannelOpen->CodecConfig.ulPhase & 0xFF ); + pApiCodecConf->byPhasingType = (UINT8)( f_pChannelOpen->CodecConfig.ulPhasingType & 0xFF ); + + /* Update the API phasing TSST structure */ + if ( f_usNewPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + { + tPOCT6100_API_PHASING_TSST pPhasingTsst; + + /* Release the previous phasing TSST if the channel was already bound to one.*/ + if ( pChanEntry->usPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( pSharedInfo, pPhasingTsst, pChanEntry->usPhasingTsstIndex ); + + pPhasingTsst->usDependencyCnt--; + } + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( pSharedInfo, pPhasingTsst, f_usNewPhasingTsstIndex ); + + pPhasingTsst->usDependencyCnt++; + pChanEntry->usPhasingTsstIndex = f_usNewPhasingTsstIndex; + + } + } + + + + return cOCT6100_ERR_OK; +} +#endif + + + + + + + + + + + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelBroadcastTsstAddSer + +Description: Assign a TSST to one of the port of an echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstAdd Pointer to TSST assign structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelBroadcastTsstAddSer +UINT32 Oct6100ChannelBroadcastTsstAddSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd ) +{ + UINT16 usChanIndex; + UINT16 usNewTsstIndex; + UINT16 usNewTsstEntry; + UINT32 ulResult; + + ulResult = Oct6100ApiCheckChanTsstAddParams( f_pApiInstance, f_pChannelTsstAdd, &usChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReserveTsstAddResources( f_pApiInstance, f_pChannelTsstAdd, usChanIndex, &usNewTsstIndex, &usNewTsstEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiWriteTsstAddStructs( f_pApiInstance, f_pChannelTsstAdd, usChanIndex, usNewTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiUpdateTsstAddChanEntry( f_pApiInstance, f_pChannelTsstAdd, usChanIndex, usNewTsstIndex, usNewTsstEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckChanTsstAddParams + +Description: Verify the validity of the tPOCT6100_CHANNEL_BROADCAST_TSST_ADD + structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstAdd Pointer to echo cancellation channel open configuration structure. +f_pusChanIndex Pointer to a structure used to store the multiple resources indexes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckChanTsstAddParams +UINT32 Oct6100ApiCheckChanTsstAddParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd, + OUT PUINT16 f_pusChanIndex ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulResult; + UINT32 ulNumTssts = 1; + UINT32 ulEntryOpenCnt; + + /* Check the provided handle. */ + if ( (f_pChannelTsstAdd->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + *f_pusChanIndex = (UINT16)( f_pChannelTsstAdd->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChanIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, *f_pusChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelTsstAdd->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + + /* validate the port parameter.*/ + if ( f_pChannelTsstAdd->ulPort != cOCT6100_CHANNEL_PORT_ROUT && + f_pChannelTsstAdd->ulPort != cOCT6100_CHANNEL_PORT_SOUT ) + return cOCT6100_ERR_CHANNEL_TSST_ADD_PORT; + + /* Get the required number of TSST based on the port.*/ + switch( f_pChannelTsstAdd->ulPort ) + { + case cOCT6100_CHANNEL_PORT_ROUT: + ulNumTssts = pChanEntry->TdmConfig.byRoutNumTssts; + break; + case cOCT6100_CHANNEL_PORT_SOUT: + ulNumTssts = pChanEntry->TdmConfig.bySoutNumTssts; + break; + default: + return cOCT6100_ERR_FATAL_B; + } + + /* Check the validity of the timeslot and stream. */ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + ulNumTssts, + f_pChannelTsstAdd->ulTimeslot, + f_pChannelTsstAdd->ulStream, + cOCT6100_OUTPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_CHANNEL_TSST_ADD_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_CHANNEL_TSST_ADD_STREAM; + } + else + { + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveTsstAddResources + +Description: Reserve the entry for the new broadcast TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstAdd Pointer to echo cancellation channel open configuration structure. +f_usChanIndex Channel index within the API's channel list. +f_pusNewTsstIndex Pointer to the new TSST index within the API's TSST memory. +f_pusNewTsstEntry Pointer to the new TSST entry within the API's TSST list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveTsstAddResources +UINT32 Oct6100ApiReserveTsstAddResources( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd, + IN UINT16 f_usChanIndex, + OUT PUINT16 f_pusNewTsstIndex, + OUT PUINT16 f_pusNewTsstEntry ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulResult; + UINT32 ulNumTssts = 1; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, f_usChanIndex ); + + switch( f_pChannelTsstAdd->ulPort ) + { + case cOCT6100_CHANNEL_PORT_ROUT: + ulNumTssts = pChanEntry->TdmConfig.byRoutNumTssts; + break; + case cOCT6100_CHANNEL_PORT_SOUT: + ulNumTssts = pChanEntry->TdmConfig.bySoutNumTssts; + break; + default: + return cOCT6100_ERR_FATAL_C; + } + + /* Reserve the new entry.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + f_pChannelTsstAdd->ulTimeslot, + f_pChannelTsstAdd->ulStream, + ulNumTssts, + cOCT6100_OUTPUT_TSST, + f_pusNewTsstIndex, + f_pusNewTsstEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteTsstAddStructs + +Description: Configure the TSST control memory for the new TSST entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstAdd Pointer to echo cancellation channel open configuration structure. +f_usChanIndex Channel index. +f_usNewTsstIndex Tsst index in the TSST control memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteTsstAddStructs +UINT32 Oct6100ApiWriteTsstAddStructs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd, + IN UINT16 f_usChanIndex, + IN UINT16 f_usNewTsstIndex ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult = cOCT6100_ERR_OK; + UINT16 usTsiMemIndex; + UINT32 ulNumTssts = 1; + + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, f_usChanIndex ); + + switch( f_pChannelTsstAdd->ulPort ) + { + case cOCT6100_CHANNEL_PORT_ROUT: + usTsiMemIndex = pChanEntry->usRinRoutTsiMemIndex; + ulNumTssts = pChanEntry->TdmConfig.byRoutNumTssts; + break; + case cOCT6100_CHANNEL_PORT_SOUT: + usTsiMemIndex = pChanEntry->usSinSoutTsiMemIndex; + ulNumTssts = pChanEntry->TdmConfig.bySoutNumTssts; + break; + default: + return cOCT6100_ERR_FATAL_D; + } + + + /* Write the new entry now.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (f_usNewTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_TSST_CONTROL_MEM_OUTPUT_TSST; + WriteParams.usWriteData |= (UINT16)( pChanEntry->CodecConfig.byAdpcmNibblePosition << cOCT6100_TSST_CONTROL_MEM_NIBBLE_POS_OFFSET ); + WriteParams.usWriteData |= (UINT16)( (ulNumTssts - 1) << cOCT6100_TSST_CONTROL_MEM_TSST_NUM_OFFSET ); + WriteParams.usWriteData |= (UINT16)( usTsiMemIndex & cOCT6100_TSST_CONTROL_MEM_TSI_MEM_MASK ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateTsstAddChanEntry + +Description: Update the associated channel API entry to add the new broacast TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstAdd Pointer to echo cancellation channel open configuration structure. +f_usChanIndex Channel index. +f_usNewTsstIndex TSST index within the TSST control memory. +f_usNewTsstEntry TSST entry within the API TSST list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateTsstAddChanEntry +UINT32 Oct6100ApiUpdateTsstAddChanEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd, + IN UINT16 f_usChanIndex, + IN UINT16 f_usNewTsstIndex, + IN UINT16 f_usNewTsstEntry ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_TSST_ENTRY pTsstEntry; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, f_usChanIndex ); + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsstEntry, f_usNewTsstEntry ); + + /* Update the channel entry.*/ + if ( f_pChannelTsstAdd->ulPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + /* Add the new TSST entry to the broadcast list.*/ + pTsstEntry->usNextEntry = pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry; + pTsstEntry->usTsstMemoryIndex = (UINT16)f_usNewTsstIndex; + pTsstEntry->usTsstValue = (UINT16)( (f_pChannelTsstAdd->ulTimeslot << 5) | f_pChannelTsstAdd->ulStream ); + + /* Modify the first entry pointer.*/ + pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry = f_usNewTsstEntry; + + /* Increment the number of broadcast TSST. */ + pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry++; + + } + else /* f_pChannelTsstAdd->ulPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + /* Add the new TSST entry to the broadcast list.*/ + pTsstEntry->usNextEntry = pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry; + pTsstEntry->usTsstMemoryIndex = (UINT16)f_usNewTsstIndex; + pTsstEntry->usTsstValue = (UINT16)( (f_pChannelTsstAdd->ulTimeslot << 5) | f_pChannelTsstAdd->ulStream ); + + /* Modify the first entry pointer.*/ + pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry = f_usNewTsstEntry; + + /* Increment the number of broadcast TSST. */ + pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry++; + } + + return cOCT6100_ERR_OK; +} +#endif + + + + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelBroadcastTsstRemoveSer + +Description: Removes a broadcast TSST from one of the output port of an + echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstRemove Pointer to TSST remove structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelBroadcastTsstRemoveSer +UINT32 Oct6100ChannelBroadcastTsstRemoveSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelTsstRemove) +{ + UINT16 usChanIndex; + UINT16 usTsstIndex; + UINT16 usTsstEntry; + UINT16 usPrevTsstEntry; + UINT32 ulResult; + + ulResult = Oct6100ApiAssertChanTsstRemoveParams( f_pApiInstance, f_pChannelTsstRemove, &usChanIndex, &usTsstIndex, &usTsstEntry, &usPrevTsstEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiInvalidateTsstRemoveStructs( f_pApiInstance, usChanIndex, usTsstIndex, f_pChannelTsstRemove->ulPort, f_pChannelTsstRemove->fRemoveAll ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseTsstRemoveResources( f_pApiInstance, f_pChannelTsstRemove, usChanIndex, usTsstIndex, usTsstEntry, usPrevTsstEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertChanTsstRemoveParams + +Description: Verify the validity of the tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE + structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstRemove Pointer to echo cancellation channel open configuration structure. +f_pulChanIndex Pointer to a channel index. +f_pulNewTsstIndex Pointer to a TSST index within the TSST control memory. +f_pulNewTsstEntry Pointer to a TSST entry within the API TSST list. +f_pulPrevTsstEntry Pointer to the previous TSST entry. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertChanTsstRemoveParams +UINT32 Oct6100ApiAssertChanTsstRemoveParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelTsstRemove, + OUT PUINT16 f_pusChanIndex, + OUT PUINT16 f_pusTsstIndex, + OUT PUINT16 f_pusTsstEntry, + OUT PUINT16 f_pusPrevTsstEntry ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_TSST_ENTRY pTsstEntry; + UINT32 ulResult; + UINT32 ulNumTssts = 1; + UINT32 ulEntryOpenCnt; + UINT16 usCurrentEntry; + UINT16 usTsstValue; + UINT16 usNumEntry; + + /* Check the provided handle. */ + if ( (f_pChannelTsstRemove->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + *f_pusChanIndex = (UINT16)( f_pChannelTsstRemove->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChanIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, *f_pusChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelTsstRemove->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + + /* validate the port parameter.*/ + if ( f_pChannelTsstRemove->ulPort != cOCT6100_CHANNEL_PORT_ROUT && + f_pChannelTsstRemove->ulPort != cOCT6100_CHANNEL_PORT_SOUT ) + return cOCT6100_ERR_CHANNEL_TSST_REMOVE_PORT; + + /* Verify that the requested entry is present in the channel's port broadcast TSST.*/ + if ( f_pChannelTsstRemove->ulPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + usCurrentEntry = pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry; + usNumEntry = pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry; + } + else /* f_pChannelTsstRemove->ulPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + usCurrentEntry = pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry; + usNumEntry = pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry; + } + + /* Verify if at least one TSST is present on the channel port.*/ + if ( usNumEntry == 0 ) + return cOCT6100_ERR_CHANNEL_TSST_REMOVE_NO_BROADCAST_TSST; + + /* Get the required number of TSST based on the port.*/ + switch( f_pChannelTsstRemove->ulPort ) + { + case cOCT6100_CHANNEL_PORT_ROUT: + ulNumTssts = pChanEntry->TdmConfig.byRoutNumTssts; + break; + case cOCT6100_CHANNEL_PORT_SOUT: + ulNumTssts = pChanEntry->TdmConfig.bySoutNumTssts; + break; + default: + return cOCT6100_ERR_FATAL_E; + } + + /* Initialize the TSST entry to invalid.*/ + *f_pusTsstEntry = cOCT6100_INVALID_INDEX; + *f_pusPrevTsstEntry = cOCT6100_INVALID_INDEX; + *f_pusTsstIndex = cOCT6100_INVALID_INDEX; + + if ( f_pChannelTsstRemove->fRemoveAll != TRUE ) + { + /* Check the validity of the timeslot and Stream.*/ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + ulNumTssts, + f_pChannelTsstRemove->ulTimeslot, + f_pChannelTsstRemove->ulStream, + cOCT6100_OUTPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_CHANNEL_TSST_REMOVE_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_CHANNEL_TSST_REMOVE_STREAM; + } + else + { + return ulResult; + } + } + + /* Set the TSST value based on the timeslot and stream value.*/ + usTsstValue = (UINT16)( (f_pChannelTsstRemove->ulTimeslot << 5) | f_pChannelTsstRemove->ulStream ); + + while( usCurrentEntry != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsstEntry, usCurrentEntry ); + + if ( usTsstValue == pTsstEntry->usTsstValue ) + { + /* A match was found.*/ + *f_pusTsstEntry = usCurrentEntry; + *f_pusTsstIndex = pTsstEntry->usTsstMemoryIndex; + break; + } + + /* Move on to the next entry.*/ + *f_pusPrevTsstEntry = usCurrentEntry; + usCurrentEntry = pTsstEntry->usNextEntry; + } + + if ( *f_pusTsstEntry == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_TSST_REMOVE_INVALID_TSST; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInvalidateTsstRemoveStructs + +Description: Invalidate the entry of the broadcast TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usChanIndex Channel index. +f_usTsstIndex TSST index within the TSST control memory. +f_ulPort Channel port where the TSST are removed from. (only used if remove all == TRUE) +f_fRemoveAll Remove all flag. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInvalidateTsstRemoveStructs +UINT32 Oct6100ApiInvalidateTsstRemoveStructs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChanIndex, + IN UINT16 f_usTsstIndex, + IN UINT32 f_ulPort, + IN BOOL f_fRemoveAll ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + if ( f_fRemoveAll == FALSE ) + { + /* Deactivate the entry now.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (f_usTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else /* f_fRemoveAll == TRUE */ + { + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_TSST_ENTRY pTsstEntry; + UINT16 usTsstEntry; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, f_usChanIndex ); + + /* Clear all entry associated to the selected port.*/ + if ( f_ulPort == cOCT6100_CHANNEL_PORT_ROUT ) + usTsstEntry = pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry; + else + usTsstEntry = pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry; + + do + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsstEntry, usTsstEntry ); + + /* Deactivate the entry now.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( ( pTsstEntry->usTsstMemoryIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usTsstEntry = pTsstEntry->usNextEntry; + + } while ( usTsstEntry != cOCT6100_INVALID_INDEX ); + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseTsstRemoveResources + +Description: Release all API resources associated to the Removed TSST and + update the channel entry accordingly. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstRemove Pointer to echo cancellation channel open configuration structure. +f_usChanIndex Channel index. +f_usTsstIndex TSST index within the TSST control memory. +f_usTsstEntry TSST entry within the API's TSST list. +f_usPrevTsstEntry Previous TSST entry within the API's TSST list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseTsstRemoveResources +UINT32 Oct6100ApiReleaseTsstRemoveResources( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelTsstRemove, + IN UINT16 f_usChanIndex, + IN UINT16 f_usTsstIndex, + IN UINT16 f_usTsstEntry, + IN UINT16 f_usPrevTsstEntry ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_TSST_ENTRY pTsstEntry; + tPOCT6100_API_TSST_ENTRY pPrevTsstEntry; + UINT16 usCurrentEntry; + UINT32 ulResult; + UINT32 ulTimeslot; + UINT32 ulStream; + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, f_usChanIndex ); + + if ( f_pChannelTsstRemove->fRemoveAll == FALSE ) + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsstEntry, f_usTsstEntry ); + + /* Update the channel entry.*/ + if ( f_pChannelTsstRemove->ulPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + /* Check if the entry was the first in the list.*/ + if ( f_usPrevTsstEntry == cOCT6100_INVALID_INDEX ) + { + pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry = pTsstEntry->usNextEntry; + } + else /* f_ulPrevTsstEntry != cOCT6100_INVALID_INDEX */ + { + /* Get a pointer to the previous entry.*/ + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPrevTsstEntry, f_usPrevTsstEntry ); + pPrevTsstEntry->usNextEntry = pTsstEntry->usNextEntry; + } + + /* Decrement the number of entry.*/ + pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry--; + } + else /* f_pChannelTsstRemove->ulPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + /* Check if the entry was the first in the list.*/ + if ( f_usPrevTsstEntry == cOCT6100_INVALID_INDEX ) + { + pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry = pTsstEntry->usNextEntry; + } + else /* f_ulPrevTsstEntry != cOCT6100_INVALID_INDEX */ + { + /* Get a pointer to the previous entry.*/ + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPrevTsstEntry, f_usPrevTsstEntry ); + pPrevTsstEntry->usNextEntry = pTsstEntry->usNextEntry; + } + + /* Decrement the number of entry.*/ + pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry--; + } + + ulTimeslot = pTsstEntry->usTsstValue >> 5; + ulStream = pTsstEntry->usTsstValue & 0x1F; + + /* Release the entry.*/ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + ulTimeslot, + ulStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_OUTPUT_TSST, + f_usTsstEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else /* f_pChannelTsstRemove->fRemoveAll == TRUE */ + { + + /* Update the channel entry.*/ + if ( f_pChannelTsstRemove->ulPort == cOCT6100_CHANNEL_PORT_ROUT ) + usCurrentEntry = pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry; + else + usCurrentEntry = pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry; + + do + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsstEntry, usCurrentEntry ); + + ulTimeslot = pTsstEntry->usTsstValue >> 5; + ulStream = pTsstEntry->usTsstValue & 0x1F; + + /* Release the entry.*/ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + ulTimeslot, + ulStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_OUTPUT_TSST, + usCurrentEntry ); /* Release the entry.*/ + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usCurrentEntry = pTsstEntry->usNextEntry; + + /* Clear the previous node.*/ + pTsstEntry->usTsstMemoryIndex = 0xFFFF; + pTsstEntry->usTsstValue = 0xFFFF; + pTsstEntry->usNextEntry = cOCT6100_INVALID_INDEX; + + } while ( usCurrentEntry != cOCT6100_INVALID_INDEX ); + + /* Reset the channel status.*/ + if ( f_pChannelTsstRemove->ulPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry = cOCT6100_INVALID_INDEX; + pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry = 0; + } + else + { + pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry = cOCT6100_INVALID_INDEX; + pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry = 0; + } + } + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiChannelGetStatsSer + +Description: Serialized function that returns all the stats of the specified + channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelStats Pointer to a channel stats structure. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiChannelGetStatsSer +UINT32 Oct6100ApiChannelGetStatsSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_STATS f_pChannelStats ) +{ + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_READ_BURST_PARAMS BurstParams; + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_TSST_ENTRY pTsstEntry; + UINT32 ulEntryOpenCnt; + UINT16 usCurrentEntry; + UINT16 usTsstCount; + UINT32 ulBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulTempData; + UINT32 ulMask; + UINT16 usChanIndex; + UINT16 ausReadData[ 32 ]; + + BYTE byRinEnergyRaw; + BYTE bySinEnergyRaw; + BYTE bySoutEnergyRaw; + INT32 lSoutEnergyIndB; + BYTE byCnEnergyRaw; + UINT16 usEchoDelayInFrames; + UINT16 usErlRaw; + + UINT32 ulResult; + UINT16 usReadData; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + BurstParams.pusReadData = ausReadData; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Check the reset stats flag.*/ + if ( f_pChannelStats->fResetStats != TRUE && f_pChannelStats->fResetStats != FALSE ) + return cOCT6100_ERR_CHANNEL_STATS_RESET; + + /* Check the provided handle. */ + if ( cOCT6100_HNDL_TAG_CHANNEL != (f_pChannelStats->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + usChanIndex = (UINT16)( f_pChannelStats->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( usChanIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, usChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelStats->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + + /* Check the value of the max broadcast tsst.*/ + if ( f_pChannelStats->TdmConfig.ulMaxBroadcastTssts > cOCT6100_MAX_TSSTS ) + return cOCT6100_ERR_CHANNEL_GET_STATS_MAX_BROADCAST_TSST; + + if ( f_pChannelStats->TdmConfig.ulMaxBroadcastTssts != 0 ) + { + /* Check if memory was allocated by the user for the stream and timeslot values.*/ + if ( f_pChannelStats->TdmConfig.pulRoutBroadcastTimeslot == NULL ) + return cOCT6100_ERR_CHANNEL_ROUT_BROADCAST_TIMESLOT; + + if ( f_pChannelStats->TdmConfig.pulRoutBroadcastStream == NULL ) + return cOCT6100_ERR_CHANNEL_ROUT_BROADCAST_STREAM; + + if ( f_pChannelStats->TdmConfig.pulSoutBroadcastTimeslot == NULL ) + return cOCT6100_ERR_CHANNEL_SOUT_BROADCAST_TIMESLOT; + + if ( f_pChannelStats->TdmConfig.pulSoutBroadcastStream == NULL ) + return cOCT6100_ERR_CHANNEL_SOUT_BROADCAST_STREAM; + } + + /* Copy the general configuration.*/ + f_pChannelStats->ulUserChanId = pChanEntry->ulUserChanId; + f_pChannelStats->ulEchoOperationMode = pChanEntry->byEchoOperationMode; + f_pChannelStats->fEnableToneDisabler = pChanEntry->fEnableToneDisabler; + f_pChannelStats->ulMutePortsMask = pChanEntry->usMutedPorts; + f_pChannelStats->fEnableExtToneDetection = pChanEntry->fEnableExtToneDetection; + + + + /* Copy the TDM configuration.*/ + f_pChannelStats->TdmConfig.ulNumRoutBroadcastTssts = pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry; + f_pChannelStats->TdmConfig.ulNumSoutBroadcastTssts = pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry; + + f_pChannelStats->TdmConfig.ulSinNumTssts = pChanEntry->TdmConfig.bySinNumTssts; + f_pChannelStats->TdmConfig.ulSinTimeslot = pChanEntry->TdmConfig.usSinTimeslot; + f_pChannelStats->TdmConfig.ulSinStream = pChanEntry->TdmConfig.usSinStream; + f_pChannelStats->TdmConfig.ulSinPcmLaw = pChanEntry->TdmConfig.bySinPcmLaw; + + f_pChannelStats->TdmConfig.ulSoutNumTssts = pChanEntry->TdmConfig.bySoutNumTssts; + f_pChannelStats->TdmConfig.ulSoutTimeslot = pChanEntry->TdmConfig.usSoutTimeslot; + f_pChannelStats->TdmConfig.ulSoutStream = pChanEntry->TdmConfig.usSoutStream; + f_pChannelStats->TdmConfig.ulSoutPcmLaw = pChanEntry->TdmConfig.bySoutPcmLaw; + + /* Copy the SOUT Broadcast TSST into the Stream and timeslot array.*/ + usCurrentEntry = pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry; + for( usTsstCount = 0; (usTsstCount < pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry) && (usTsstCount < f_pChannelStats->TdmConfig.ulMaxBroadcastTssts); usTsstCount++ ) + { + if ( usCurrentEntry == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_FATAL_F; + + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsstEntry, usCurrentEntry ); + + f_pChannelStats->TdmConfig.pulSoutBroadcastStream[ usTsstCount ] = pTsstEntry->usTsstValue & 0x1F; + f_pChannelStats->TdmConfig.pulSoutBroadcastStream[ usTsstCount ] = pTsstEntry->usTsstValue >> 5; + + /* Obtain the index of the next entry.*/ + usCurrentEntry = pTsstEntry->usNextEntry; + } + + /* Check if all Sout Broadcast TSST were returned.*/ + if ( usTsstCount < pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry ) + { + f_pChannelStats->TdmConfig.fMoreSoutBroadcastTssts = TRUE; + } + else /* usTsstCount >= pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry */ + { + f_pChannelStats->TdmConfig.fMoreSoutBroadcastTssts = FALSE; + } + + f_pChannelStats->TdmConfig.ulRinNumTssts = pChanEntry->TdmConfig.byRinNumTssts; + f_pChannelStats->TdmConfig.ulRinTimeslot = pChanEntry->TdmConfig.usRinTimeslot; + f_pChannelStats->TdmConfig.ulRinStream = pChanEntry->TdmConfig.usRinStream; + f_pChannelStats->TdmConfig.ulRinPcmLaw = pChanEntry->TdmConfig.byRinPcmLaw; + + f_pChannelStats->TdmConfig.ulRoutNumTssts = pChanEntry->TdmConfig.byRoutNumTssts; + f_pChannelStats->TdmConfig.ulRoutTimeslot = pChanEntry->TdmConfig.usRoutTimeslot; + f_pChannelStats->TdmConfig.ulRoutStream = pChanEntry->TdmConfig.usRoutStream; + f_pChannelStats->TdmConfig.ulRoutPcmLaw = pChanEntry->TdmConfig.byRoutPcmLaw; + + + /* Copy the ROUT Broadcast TSST into the Stream and timeslot array.*/ + usCurrentEntry = pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry; + for( usTsstCount = 0; (usTsstCount < pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry) && (usTsstCount < f_pChannelStats->TdmConfig.ulMaxBroadcastTssts); usTsstCount++ ) + { + if ( usCurrentEntry == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_FATAL_10; + + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsstEntry, usCurrentEntry ); + + f_pChannelStats->TdmConfig.pulRoutBroadcastStream[ usTsstCount ] = pTsstEntry->usTsstValue & 0x1F; + f_pChannelStats->TdmConfig.pulRoutBroadcastStream[ usTsstCount ] = pTsstEntry->usTsstValue >> 5; + + /* Obtain the index of the next entry.*/ + usCurrentEntry = pTsstEntry->usNextEntry; + } + + /* Check if all Rout Broadcast TSST were returned.*/ + if ( usTsstCount < pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry ) + { + f_pChannelStats->TdmConfig.fMoreRoutBroadcastTssts = TRUE; + } + else /* usTsstCount >= pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry */ + { + f_pChannelStats->TdmConfig.fMoreRoutBroadcastTssts = FALSE; + } + + /* Copy the VQE configuration.*/ + f_pChannelStats->VqeConfig.fEnableNlp = pChanEntry->VqeConfig.fEnableNlp; + f_pChannelStats->VqeConfig.ulComfortNoiseMode = pChanEntry->VqeConfig.byComfortNoiseMode; + f_pChannelStats->VqeConfig.fEnableTailDisplacement = pChanEntry->VqeConfig.fEnableTailDisplacement; + if ( pChanEntry->VqeConfig.usTailDisplacement != cOCT6100_AUTO_SELECT_TAIL ) + f_pChannelStats->VqeConfig.ulTailDisplacement = pChanEntry->VqeConfig.usTailDisplacement; + else + f_pChannelStats->VqeConfig.ulTailDisplacement = f_pApiInstance->pSharedInfo->ChipConfig.usTailDisplacement; + + if ( pChanEntry->VqeConfig.usTailLength != cOCT6100_AUTO_SELECT_TAIL ) + f_pChannelStats->VqeConfig.ulTailLength = pChanEntry->VqeConfig.usTailLength; + else + f_pChannelStats->VqeConfig.ulTailLength = f_pApiInstance->pSharedInfo->ImageInfo.usMaxTailLength; + + + + f_pChannelStats->VqeConfig.fSinDcOffsetRemoval = pChanEntry->VqeConfig.fSinDcOffsetRemoval; + f_pChannelStats->VqeConfig.fRinDcOffsetRemoval = pChanEntry->VqeConfig.fRinDcOffsetRemoval; + f_pChannelStats->VqeConfig.fRinLevelControl = pChanEntry->VqeConfig.fRinLevelControl; + f_pChannelStats->VqeConfig.fSoutLevelControl = pChanEntry->VqeConfig.fSoutLevelControl; + f_pChannelStats->VqeConfig.fRinAutomaticLevelControl = pChanEntry->VqeConfig.fRinAutomaticLevelControl; + f_pChannelStats->VqeConfig.fSoutAutomaticLevelControl = pChanEntry->VqeConfig.fSoutAutomaticLevelControl; + f_pChannelStats->VqeConfig.fRinHighLevelCompensation = pChanEntry->VqeConfig.fRinHighLevelCompensation; + f_pChannelStats->VqeConfig.fSoutAdaptiveNoiseReduction = pChanEntry->VqeConfig.fSoutAdaptiveNoiseReduction; + f_pChannelStats->VqeConfig.fSoutNoiseBleaching = pChanEntry->VqeConfig.fSoutNoiseBleaching; + f_pChannelStats->VqeConfig.fSoutConferencingNoiseReduction = pChanEntry->VqeConfig.fSoutConferencingNoiseReduction; + f_pChannelStats->VqeConfig.lRinLevelControlGainDb = pChanEntry->VqeConfig.chRinLevelControlGainDb; + f_pChannelStats->VqeConfig.lSoutLevelControlGainDb = pChanEntry->VqeConfig.chSoutLevelControlGainDb; + f_pChannelStats->VqeConfig.lRinAutomaticLevelControlTargetDb = pChanEntry->VqeConfig.chRinAutomaticLevelControlTargetDb; + f_pChannelStats->VqeConfig.lSoutAutomaticLevelControlTargetDb = pChanEntry->VqeConfig.chSoutAutomaticLevelControlTargetDb; + f_pChannelStats->VqeConfig.lRinHighLevelCompensationThresholdDb = pChanEntry->VqeConfig.chRinHighLevelCompensationThresholdDb; + f_pChannelStats->VqeConfig.fAcousticEcho = pChanEntry->VqeConfig.fAcousticEcho; + f_pChannelStats->VqeConfig.fDtmfToneRemoval = pChanEntry->VqeConfig.fDtmfToneRemoval; + + f_pChannelStats->VqeConfig.lDefaultErlDb = pChanEntry->VqeConfig.chDefaultErlDb; + f_pChannelStats->VqeConfig.lAecDefaultErlDb = pChanEntry->VqeConfig.chAecDefaultErlDb; + f_pChannelStats->VqeConfig.ulAecTailLength = pChanEntry->VqeConfig.usAecTailLength; + f_pChannelStats->VqeConfig.lAnrSnrEnhancementDb = pChanEntry->VqeConfig.chAnrSnrEnhancementDb; + f_pChannelStats->VqeConfig.ulAnrVoiceNoiseSegregation = pChanEntry->VqeConfig.byAnrVoiceNoiseSegregation; + f_pChannelStats->VqeConfig.ulToneDisablerVqeActivationDelay = pChanEntry->VqeConfig.usToneDisablerVqeActivationDelay; + f_pChannelStats->VqeConfig.ulNonLinearityBehaviorA = pChanEntry->VqeConfig.byNonLinearityBehaviorA; + f_pChannelStats->VqeConfig.ulNonLinearityBehaviorB = pChanEntry->VqeConfig.byNonLinearityBehaviorB; + f_pChannelStats->VqeConfig.ulDoubleTalkBehavior = pChanEntry->VqeConfig.byDoubleTalkBehavior; + f_pChannelStats->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb = pChanEntry->VqeConfig.bySoutAutomaticListenerEnhancementGainDb; + f_pChannelStats->VqeConfig.ulSoutNaturalListenerEnhancementGainDb = pChanEntry->VqeConfig.bySoutNaturalListenerEnhancementGainDb; + f_pChannelStats->VqeConfig.fSoutNaturalListenerEnhancement = pChanEntry->VqeConfig.fSoutNaturalListenerEnhancement; + f_pChannelStats->VqeConfig.fRoutNoiseReduction = pChanEntry->VqeConfig.fRoutNoiseReduction; + f_pChannelStats->VqeConfig.lRoutNoiseReductionLevelGainDb = pChanEntry->VqeConfig.chRoutNoiseReductionLevelGainDb; + f_pChannelStats->VqeConfig.fEnableMusicProtection = pChanEntry->VqeConfig.fEnableMusicProtection; + f_pChannelStats->VqeConfig.fIdleCodeDetection = pChanEntry->VqeConfig.fIdleCodeDetection; + + /* Copy the CODEC configuration.*/ + f_pChannelStats->CodecConfig.ulAdpcmNibblePosition = pChanEntry->CodecConfig.byAdpcmNibblePosition; + + f_pChannelStats->CodecConfig.ulEncoderPort = pChanEntry->CodecConfig.byEncoderPort; + f_pChannelStats->CodecConfig.ulEncodingRate = pChanEntry->CodecConfig.byEncodingRate; + + f_pChannelStats->CodecConfig.ulDecoderPort = pChanEntry->CodecConfig.byDecoderPort; + f_pChannelStats->CodecConfig.ulDecodingRate = pChanEntry->CodecConfig.byDecodingRate; + + f_pChannelStats->CodecConfig.fEnableSilenceSuppression = pChanEntry->CodecConfig.fEnableSilenceSuppression; + f_pChannelStats->CodecConfig.ulPhase = pChanEntry->CodecConfig.byPhase; + f_pChannelStats->CodecConfig.ulPhasingType = pChanEntry->CodecConfig.byPhasingType; + + if ( pChanEntry->usPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + { + tPOCT6100_API_PHASING_TSST pPhasingTsstEntry; + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPhasingTsstEntry, pChanEntry->usPhasingTsstIndex ); + + f_pChannelStats->CodecConfig.ulPhasingTsstHndl = cOCT6100_HNDL_TAG_PHASING_TSST | (pPhasingTsstEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | pChanEntry->usPhasingTsstIndex; + } + else + { + f_pChannelStats->CodecConfig.ulPhasingTsstHndl = cOCT6100_INVALID_HANDLE; + } + + + /* Reset the stats and exit if the reset flag is set.*/ + if ( f_pChannelStats->fResetStats == TRUE ) + { + pChanEntry->sMaxERLE = cOCT6100_INVALID_SIGNED_STAT_W; + pChanEntry->sMaxERL = cOCT6100_INVALID_SIGNED_STAT_W; + pChanEntry->usMaxEchoDelay = cOCT6100_INVALID_STAT_W; + } + + /*---------------------------------------------------------------------*/ + /* Update the API internal stats.*/ + + BurstParams.ulReadAddress = f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemBase + (usChanIndex * f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ); + BurstParams.ulReadAddress += f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoStatsOfst; + BurstParams.ulReadLength = f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoStatsSize / 2; /* Length in words.*/ + + mOCT6100_DRIVER_READ_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the energy stat are found in the new memory location. */ + if ( ( pSharedInfo->ImageInfo.fRinEnergyStat == TRUE ) + && ( pSharedInfo->ImageInfo.fSoutEnergyStat == TRUE ) ) + { + ulFeatureBytesOffset = f_pApiInstance->pSharedInfo->MemoryMap.RinEnergyStatFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = f_pApiInstance->pSharedInfo->MemoryMap.RinEnergyStatFieldOfst.byBitOffset; + ulFeatureFieldLength = f_pApiInstance->pSharedInfo->MemoryMap.RinEnergyStatFieldOfst.byFieldSize; + + ReadParams.ulReadAddress = f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemBase + (usChanIndex * f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ); + ReadParams.ulReadAddress += f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst + ulFeatureBytesOffset; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulFeatureBitOffset < 16 ) + ReadParams.ulReadAddress += 2; + + /* Must read in memory directly since this value is changed by hardware */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulFeatureBitOffset < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + /* Clear previous value set in the feature field. */ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= ulMask; + + /* Shift to get value. */ + ulTempData = ulTempData >> ulFeatureBitOffset; + + /* Overwrite value read the old way. */ + ausReadData[ 0 ] &= 0x00FF; + ausReadData[ 0 ] |= (UINT16)( ( ulTempData << 8 ) & 0xFF00 ); + + ulFeatureBytesOffset = f_pApiInstance->pSharedInfo->MemoryMap.SoutEnergyStatFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = f_pApiInstance->pSharedInfo->MemoryMap.SoutEnergyStatFieldOfst.byBitOffset; + ulFeatureFieldLength = f_pApiInstance->pSharedInfo->MemoryMap.SoutEnergyStatFieldOfst.byFieldSize; + + ReadParams.ulReadAddress = f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemBase + (usChanIndex * f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ); + ReadParams.ulReadAddress += f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst + ulFeatureBytesOffset; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulFeatureBitOffset < 16 ) + ReadParams.ulReadAddress += 2; + + /* Must read in memory directly since this value is changed by hardware */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulFeatureBitOffset < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + /* Clear previous value set in the feature field. */ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= ulMask; + + /* Shift to get value. */ + ulTempData = ulTempData >> ulFeatureBitOffset; + + /* Overwrite value read the old way. */ + ausReadData[ 1 ] &= 0x00FF; + ausReadData[ 1 ] |= (UINT16)( ( ulTempData << 8 ) & 0xFF00 ); + } + + byRinEnergyRaw = (BYTE)(( ausReadData[ 0 ] >> 8 ) & 0xFF); + bySinEnergyRaw = (BYTE)(( ausReadData[ 0 ] >> 0 ) & 0xFF); + bySoutEnergyRaw = (BYTE)(( ausReadData[ 1 ] >> 8 ) & 0xFF); + byCnEnergyRaw = (BYTE)(( ausReadData[ 5 ] >> 8 ) & 0xFF); + + usEchoDelayInFrames = (UINT16)(ausReadData[ 4 ]); + usErlRaw = ausReadData[ 2 ]; + + pChanEntry->byToneDisablerStatus = (UINT8)(( ausReadData[ 5 ] >> 0 ) & 0xFF); + if ( f_pChannelStats->fResetStats == TRUE ) + { + pChanEntry->usNumEchoPathChangesOfst = (UINT16)(ausReadData[ 3 ]); + pChanEntry->usNumEchoPathChanges = 0; + } + else /* if ( f_pChannelStats->fResetStats == FALSE ) */ + { + pChanEntry->usNumEchoPathChanges = (UINT16)( ausReadData[ 3 ] - pChanEntry->usNumEchoPathChangesOfst ); + } + + pChanEntry->sComfortNoiseLevel = (INT16)( Oct6100ApiOctFloatToDbEnergyByte( byCnEnergyRaw ) & 0xFFFF ); + pChanEntry->sComfortNoiseLevel -= 12; + pChanEntry->sRinLevel = (INT16)( Oct6100ApiOctFloatToDbEnergyByte( byRinEnergyRaw ) & 0xFFFF ); + pChanEntry->sRinLevel -= 12; + pChanEntry->sSinLevel = (INT16)( Oct6100ApiOctFloatToDbEnergyByte( bySinEnergyRaw ) & 0xFFFF ); + pChanEntry->sSinLevel -= 12; + lSoutEnergyIndB = Oct6100ApiOctFloatToDbEnergyByte( bySoutEnergyRaw ); + lSoutEnergyIndB -= 12; + + /* Process some stats only if the channel is converged.*/ + if ( ( usEchoDelayInFrames != cOCT6100_INVALID_ECHO_DELAY ) + && ( pChanEntry->byEchoOperationMode != cOCT6100_ECHO_OP_MODE_POWER_DOWN ) + && ( pChanEntry->byEchoOperationMode != cOCT6100_ECHO_OP_MODE_HT_RESET ) ) + { + /* Update the current ERL. */ + pChanEntry->sCurrentERL = (INT16)( Oct6100ApiOctFloatToDbEnergyHalf( usErlRaw ) & 0xFFFF ); + pChanEntry->sCurrentERLE = (INT16)( ( lSoutEnergyIndB - pChanEntry->sSinLevel ) & 0xFFFF ); + pChanEntry->usCurrentEchoDelay = (UINT16)( usEchoDelayInFrames / 8 ); /* To convert in msec.*/ + + /* Update the max value if required.*/ + if ( pChanEntry->usCurrentEchoDelay > pChanEntry->usMaxEchoDelay || + pChanEntry->usMaxEchoDelay == cOCT6100_INVALID_STAT_W ) + { + pChanEntry->usMaxEchoDelay = pChanEntry->usCurrentEchoDelay; + } + + if ( pChanEntry->sCurrentERL > pChanEntry->sMaxERL || + pChanEntry->sMaxERL == cOCT6100_INVALID_SIGNED_STAT_W ) + { + pChanEntry->sMaxERL = pChanEntry->sCurrentERL; + } + + if ( pChanEntry->sCurrentERLE > pChanEntry->sMaxERLE || + pChanEntry->sMaxERLE == cOCT6100_INVALID_SIGNED_STAT_W ) + { + pChanEntry->sMaxERLE = pChanEntry->sCurrentERLE; + } + } + else + { + pChanEntry->sCurrentERLE = cOCT6100_INVALID_SIGNED_STAT_W; + pChanEntry->sCurrentERL = cOCT6100_INVALID_SIGNED_STAT_W; + pChanEntry->usCurrentEchoDelay = cOCT6100_INVALID_STAT_W; + } + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fRinAppliedGainStat == TRUE ) + { + /* Calculate base address for auto level control + high level compensation configuration. */ + ulBaseAddress = f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemBase + ( usChanIndex * f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst; + + ulFeatureBytesOffset = f_pApiInstance->pSharedInfo->MemoryMap.RinAppliedGainStatOfst.usDwordOffset * 4; + ulFeatureBitOffset = f_pApiInstance->pSharedInfo->MemoryMap.RinAppliedGainStatOfst.byBitOffset; + ulFeatureFieldLength = f_pApiInstance->pSharedInfo->MemoryMap.RinAppliedGainStatOfst.byFieldSize; + + ReadParams.ulReadAddress = ulBaseAddress + ulFeatureBytesOffset; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulFeatureBitOffset < 16 ) + ReadParams.ulReadAddress += 2; + + /* Must read in memory directly since this value is changed by hardware */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulFeatureBitOffset < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= ulMask; + + /* Shift to get value. */ + ulTempData = ulTempData >> ulFeatureBitOffset; + + pChanEntry->sRinAppliedGain = (INT16)( 2 * (INT16)( Oct6100ApiOctFloatToDbEnergyHalf( (UINT16)( ulTempData & 0xFFFF ) ) & 0xFFFF ) ); + } + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fSoutAppliedGainStat == TRUE ) + { + /* Calculate base address for auto level control + high level compensation configuration. */ + ulBaseAddress = f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemBase + ( usChanIndex * f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst; + + ulFeatureBytesOffset = f_pApiInstance->pSharedInfo->MemoryMap.SoutAppliedGainStatOfst.usDwordOffset * 4; + ulFeatureBitOffset = f_pApiInstance->pSharedInfo->MemoryMap.SoutAppliedGainStatOfst.byBitOffset; + ulFeatureFieldLength = f_pApiInstance->pSharedInfo->MemoryMap.SoutAppliedGainStatOfst.byFieldSize; + + ReadParams.ulReadAddress = ulBaseAddress + ulFeatureBytesOffset; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulFeatureBitOffset < 16 ) + ReadParams.ulReadAddress += 2; + + /* Must read in memory directly since this value is changed by hardware */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulFeatureBitOffset < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + /* Clear previous value set in the feature field. */ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= ulMask; + + /* Shift to get value. */ + ulTempData = ulTempData >> ulFeatureBitOffset; + + pChanEntry->sSoutAppliedGain = (INT16)( 2 * (INT16)( Oct6100ApiOctFloatToDbEnergyHalf( (UINT16)( ulTempData & 0xFFFF ) ) & 0xFFFF ) ); + } + + /*---------------------------------------------------------------------*/ + /* Return the real stats.*/ + + f_pChannelStats->ulNumEchoPathChanges = pChanEntry->usNumEchoPathChanges; + if ( usEchoDelayInFrames != cOCT6100_INVALID_ECHO_DELAY ) + { + f_pChannelStats->fEchoCancellerConverged = TRUE; + } + else + { + f_pChannelStats->fEchoCancellerConverged = FALSE; + } + if ( pChanEntry->sCurrentERL == cOCT6100_INVALID_SIGNED_STAT_W ) + f_pChannelStats->lCurrentERL = cOCT6100_INVALID_SIGNED_STAT; + else + f_pChannelStats->lCurrentERL = pChanEntry->sCurrentERL; + + if ( pChanEntry->sMaxERL == cOCT6100_INVALID_SIGNED_STAT_W ) + f_pChannelStats->lMaxERL = cOCT6100_INVALID_SIGNED_STAT; + else + f_pChannelStats->lMaxERL = pChanEntry->sMaxERL; + + if ( pChanEntry->usMaxEchoDelay == cOCT6100_INVALID_STAT_W ) + f_pChannelStats->ulMaxEchoDelay = cOCT6100_INVALID_STAT; + else + f_pChannelStats->ulMaxEchoDelay = pChanEntry->usMaxEchoDelay; + + if ( pChanEntry->sRinLevel == cOCT6100_INVALID_SIGNED_STAT_W ) + f_pChannelStats->lRinLevel = cOCT6100_INVALID_SIGNED_STAT; + else + f_pChannelStats->lRinLevel = pChanEntry->sRinLevel; + + if ( pSharedInfo->ImageInfo.fSinLevel == TRUE ) + { + if ( pChanEntry->sSinLevel == cOCT6100_INVALID_SIGNED_STAT_W ) + f_pChannelStats->lSinLevel = cOCT6100_INVALID_SIGNED_STAT; + else + f_pChannelStats->lSinLevel = pChanEntry->sSinLevel; + } + else /* if ( pSharedInfo->ImageInfo.fSinLevel != TRUE ) */ + { + /* SIN level is not supported in this image. */ + f_pChannelStats->lSinLevel = cOCT6100_INVALID_SIGNED_STAT; + } + + f_pChannelStats->lRinAppliedGain = pChanEntry->VqeConfig.chRinLevelControlGainDb; + if ( ( f_pApiInstance->pSharedInfo->ImageInfo.fRinAppliedGainStat == TRUE ) + && ( ( pChanEntry->VqeConfig.fRinAutomaticLevelControl == TRUE ) + || ( pChanEntry->VqeConfig.fRinHighLevelCompensation == TRUE ) ) ) + { + f_pChannelStats->lRinAppliedGain = pChanEntry->sRinAppliedGain; + } + + f_pChannelStats->lSoutAppliedGain = pChanEntry->VqeConfig.chSoutLevelControlGainDb; + if ( ( f_pApiInstance->pSharedInfo->ImageInfo.fSoutAppliedGainStat == TRUE ) + && ( pChanEntry->VqeConfig.fSoutAutomaticLevelControl == TRUE ) ) + { + f_pChannelStats->lSoutAppliedGain = pChanEntry->sSoutAppliedGain; + } + + if ( pChanEntry->usCurrentEchoDelay == cOCT6100_INVALID_STAT_W ) + f_pChannelStats->ulCurrentEchoDelay = cOCT6100_INVALID_STAT; + else + f_pChannelStats->ulCurrentEchoDelay = pChanEntry->usCurrentEchoDelay; + + if ( pSharedInfo->ImageInfo.fSinLevel == TRUE ) + { + if ( pChanEntry->sCurrentERLE == cOCT6100_INVALID_SIGNED_STAT_W ) + f_pChannelStats->lCurrentERLE = cOCT6100_INVALID_SIGNED_STAT; + else + f_pChannelStats->lCurrentERLE = pChanEntry->sCurrentERLE; + } + else /* if ( pSharedInfo->ImageInfo.fSinLevel != TRUE ) */ + { + f_pChannelStats->lCurrentERLE = cOCT6100_INVALID_SIGNED_STAT; + } + + if ( pSharedInfo->ImageInfo.fSinLevel == TRUE ) + { + if ( pChanEntry->sMaxERLE == cOCT6100_INVALID_SIGNED_STAT_W ) + f_pChannelStats->lMaxERLE = cOCT6100_INVALID_SIGNED_STAT; + else + f_pChannelStats->lMaxERLE = pChanEntry->sMaxERLE; + } + else /* if ( pSharedInfo->ImageInfo.fSinLevel != TRUE ) */ + { + f_pChannelStats->lMaxERLE = cOCT6100_INVALID_SIGNED_STAT; + } + + f_pChannelStats->lComfortNoiseLevel = pChanEntry->sComfortNoiseLevel; + f_pChannelStats->ulToneDisablerStatus = pChanEntry->byToneDisablerStatus; + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fSinVoiceDetectedStat == TRUE ) + { + UINT32 ulVoiceDetectedBytesOfst = f_pApiInstance->pSharedInfo->MemoryMap.SinVoiceDetectedStatOfst.usDwordOffset * 4; + UINT32 ulVoiceDetectedBitOfst = f_pApiInstance->pSharedInfo->MemoryMap.SinVoiceDetectedStatOfst.byBitOffset; + UINT32 ulVoiceDetectedFieldSize = f_pApiInstance->pSharedInfo->MemoryMap.SinVoiceDetectedStatOfst.byFieldSize; + + /* Set the channel root base address.*/ + UINT32 ulChannelRootBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( usChanIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanRootConfOfst; + + ReadParams.ulReadAddress = ulChannelRootBaseAddress + ulVoiceDetectedBytesOfst; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulVoiceDetectedBitOfst < 16 ) + ReadParams.ulReadAddress += 2; + + /* Must read in memory directly since this value is changed by hardware */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulVoiceDetectedBitOfst < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + mOCT6100_CREATE_FEATURE_MASK( ulVoiceDetectedFieldSize, ulVoiceDetectedBitOfst, &ulMask ); + + if ( ( ulTempData & ulMask ) != 0x0 ) + f_pChannelStats->fSinVoiceDetected = TRUE; + else + f_pChannelStats->fSinVoiceDetected = FALSE; + } + + /*---------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveEchoEntry + +Description: Reserves one of the echo channel API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pusEchoIndex Resulting index reserved in the echo channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveEchoEntry +UINT32 Oct6100ApiReserveEchoEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusEchoIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pEchoAlloc; + UINT32 ulResult; + UINT32 ulEchoIndex; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_CHANNEL_ALLOC_PNT( pSharedInfo, pEchoAlloc ) + + ulResult = OctapiLlmAllocAlloc( pEchoAlloc, &ulEchoIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_CHANNEL_ALL_CHANNELS_ARE_OPENED; + else + return cOCT6100_ERR_FATAL_11; + } + + *f_pusEchoIndex = (UINT16)( ulEchoIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseEchoEntry + +Description: Releases the specified ECHO channel API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usEchoIndex Index reserved in the echo channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseEchoEntry +UINT32 Oct6100ApiReleaseEchoEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEchoIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pEchoAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_CHANNEL_ALLOC_PNT( pSharedInfo, pEchoAlloc ) + + ulResult = OctapiLlmAllocDealloc( pEchoAlloc, f_usEchoIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_12; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveBiDirChanEntry + +Description: Reserves one of the bidirectional channel API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pusBiDirChanIndex Resulting index reserved in the bidir channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveBiDirChanEntry +UINT32 Oct6100ApiReserveBiDirChanEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusBiDirChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pChanAlloc; + UINT32 ulResult; + UINT32 ulBiDirChanIndex; + + /* Get local pointer to shared portion of the API instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_BIDIR_CHANNEL_ALLOC_PNT( pSharedInfo, pChanAlloc ) + + ulResult = OctapiLlmAllocAlloc( pChanAlloc, &ulBiDirChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_CHANNEL_ALL_BIDIR_CHANNELS_ARE_OPENED; + else + return cOCT6100_ERR_FATAL_9F; + } + + *f_pusBiDirChanIndex = (UINT16)( ulBiDirChanIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseBiDirChanEntry + +Description: Releases the specified bidirectional channel API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulBiDirChanIndex Bidirectional channel index within the API's Bidir channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseBiDirChanEntry +UINT32 Oct6100ApiReleaseBiDirChanEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulBiDirChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pChanAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_BIDIR_CHANNEL_ALLOC_PNT( pSharedInfo, pChanAlloc ) + + ulResult = OctapiLlmAllocDealloc( pChanAlloc, f_ulBiDirChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_A0; + } + + return cOCT6100_ERR_OK; +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckTdmConfig + +Description: This function will check the validity of the TDM config parameter + of an Open TDM config structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pTdmConfig TDM config of the channel. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckTdmConfig +UINT32 Oct6100ApiCheckTdmConfig( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_TDM f_pTdmConfig ) +{ + UINT32 ulResult; + + /*==============================================================================*/ + /* Check the TDM configuration parameters.*/ + + /* Check the validity of the timeslot and Stream only if it is defined.*/ + if ( f_pTdmConfig->ulRinTimeslot != cOCT6100_UNASSIGNED || + f_pTdmConfig->ulRinStream != cOCT6100_UNASSIGNED ) + { + if ( f_pTdmConfig->ulRinNumTssts != 1 && + f_pTdmConfig->ulRinNumTssts != 2 ) + return cOCT6100_ERR_CHANNEL_RIN_NUM_TSSTS; + + /* Check the RIN TDM streams, timeslots component for errors.*/ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + f_pTdmConfig->ulRinNumTssts, + f_pTdmConfig->ulRinTimeslot, + f_pTdmConfig->ulRinStream, + cOCT6100_INPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_CHANNEL_RIN_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_CHANNEL_RIN_STREAM; + } + else + { + return ulResult; + } + } + } + + /* Check the validity of the timeslot and Stream only if it is defined.*/ + if ( f_pTdmConfig->ulRoutTimeslot != cOCT6100_UNASSIGNED || + f_pTdmConfig->ulRoutStream != cOCT6100_UNASSIGNED ) + { + if ( f_pTdmConfig->ulRoutNumTssts != 1 && + f_pTdmConfig->ulRoutNumTssts != 2 ) + return cOCT6100_ERR_CHANNEL_ROUT_NUM_TSSTS; + + /* Check the ROUT TDM streams, timeslots component for errors.*/ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + f_pTdmConfig->ulRoutNumTssts, + f_pTdmConfig->ulRoutTimeslot, + f_pTdmConfig->ulRoutStream, + cOCT6100_OUTPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_CHANNEL_ROUT_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_CHANNEL_ROUT_STREAM; + } + else + { + return ulResult; + } + } + } + + /* Check the validity of the timeslot and Stream only if it is defined.*/ + if ( f_pTdmConfig->ulSinTimeslot != cOCT6100_UNASSIGNED || + f_pTdmConfig->ulSinStream != cOCT6100_UNASSIGNED ) + { + if ( f_pTdmConfig->ulSinNumTssts != 1 && + f_pTdmConfig->ulSinNumTssts != 2 ) + return cOCT6100_ERR_CHANNEL_SIN_NUM_TSSTS; + + /* Check the SIN TDM streams, timeslots component for errors.*/ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + f_pTdmConfig->ulSinNumTssts, + f_pTdmConfig->ulSinTimeslot, + f_pTdmConfig->ulSinStream, + cOCT6100_INPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_CHANNEL_SIN_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_CHANNEL_SIN_STREAM; + } + else + { + return ulResult; + } + } + } + + /* Check the validity of the timeslot and Stream only if it is defined.*/ + if ( f_pTdmConfig->ulSoutTimeslot != cOCT6100_UNASSIGNED || + f_pTdmConfig->ulSoutStream != cOCT6100_UNASSIGNED ) + { + if ( f_pTdmConfig->ulSoutNumTssts != 1 && + f_pTdmConfig->ulSoutNumTssts != 2 ) + return cOCT6100_ERR_CHANNEL_SOUT_NUM_TSSTS; + + /* Check the ROUT TDM streams, timeslots component for errors.*/ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + f_pTdmConfig->ulSoutNumTssts, + f_pTdmConfig->ulSoutTimeslot, + f_pTdmConfig->ulSoutStream, + cOCT6100_OUTPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_CHANNEL_SOUT_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_CHANNEL_SOUT_STREAM; + } + else + { + return ulResult; + } + } + } + + /* Check the PCM law parameters.*/ + if ( f_pTdmConfig->ulRinPcmLaw != cOCT6100_PCM_U_LAW && + f_pTdmConfig->ulRinPcmLaw != cOCT6100_PCM_A_LAW ) + return cOCT6100_ERR_CHANNEL_RIN_PCM_LAW; + + if ( f_pTdmConfig->ulSinPcmLaw != cOCT6100_PCM_U_LAW && + f_pTdmConfig->ulSinPcmLaw != cOCT6100_PCM_A_LAW ) + return cOCT6100_ERR_CHANNEL_SIN_PCM_LAW; + + if ( f_pTdmConfig->ulRoutPcmLaw != cOCT6100_PCM_U_LAW && + f_pTdmConfig->ulRoutPcmLaw != cOCT6100_PCM_A_LAW ) + return cOCT6100_ERR_CHANNEL_ROUT_PCM_LAW; + + if ( f_pTdmConfig->ulSoutPcmLaw != cOCT6100_PCM_U_LAW && + f_pTdmConfig->ulSoutPcmLaw != cOCT6100_PCM_A_LAW ) + return cOCT6100_ERR_CHANNEL_SOUT_PCM_LAW; + + /*==============================================================================*/ + + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckVqeConfig + +Description: This function will check the validity of the VQE config parameter + of an Open VQE config structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pVqeConfig VQE config of the channel. +f_fEnableToneDisabler Whether the tone disabler is active or not. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckVqeConfig +UINT32 Oct6100ApiCheckVqeConfig( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN BOOL f_fEnableToneDisabler ) +{ + tPOCT6100_API_IMAGE_INFO pImageInfo; + + pImageInfo = &f_pApiInstance->pSharedInfo->ImageInfo; + + if ( f_pVqeConfig->fEnableNlp != TRUE && f_pVqeConfig->fEnableNlp != FALSE ) + return cOCT6100_ERR_CHANNEL_ENABLE_NLP; + + if ( f_pVqeConfig->fEnableNlp == TRUE && pImageInfo->fNlpControl == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NLP_CONTROL; + + + + /* Check the comfort noise mode.*/ + if ( f_pVqeConfig->ulComfortNoiseMode != cOCT6100_COMFORT_NOISE_OFF && pImageInfo->fComfortNoise == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_BKG_NOISE_FREEZE; + + if ( f_pVqeConfig->ulComfortNoiseMode != cOCT6100_COMFORT_NOISE_NORMAL && + f_pVqeConfig->ulComfortNoiseMode != cOCT6100_COMFORT_NOISE_EXTENDED && + f_pVqeConfig->ulComfortNoiseMode != cOCT6100_COMFORT_NOISE_FAST_LATCH && + f_pVqeConfig->ulComfortNoiseMode != cOCT6100_COMFORT_NOISE_OFF ) + return cOCT6100_ERR_CHANNEL_COMFORT_NOISE_MODE; + + /* Check the DC offset removal.*/ + if ( f_pVqeConfig->fSinDcOffsetRemoval != TRUE && f_pVqeConfig->fSinDcOffsetRemoval != FALSE ) + return cOCT6100_ERR_CHANNEL_SIN_DC_OFFSET_REM; + + if ( f_pVqeConfig->fSinDcOffsetRemoval == TRUE && pImageInfo->fSinDcOffsetRemoval == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SIN_DC_OFFSET_REM; + + if ( f_pVqeConfig->fRinDcOffsetRemoval != TRUE && f_pVqeConfig->fRinDcOffsetRemoval != FALSE ) + return cOCT6100_ERR_CHANNEL_RIN_DC_OFFSET_REM; + + if ( f_pVqeConfig->fRinDcOffsetRemoval == TRUE && pImageInfo->fRinDcOffsetRemoval == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_RIN_DC_OFFSET_REM; + + /* Check the Level control.*/ + if ( f_pVqeConfig->fRinLevelControl != TRUE && f_pVqeConfig->fRinLevelControl != FALSE ) + return cOCT6100_ERR_CHANNEL_RIN_LEVEL_CONTROL; + + if ( f_pVqeConfig->fSoutLevelControl != TRUE && f_pVqeConfig->fSoutLevelControl != FALSE ) + return cOCT6100_ERR_CHANNEL_SOUT_LEVEL_CONTROL; + + if ( ( f_pVqeConfig->lRinLevelControlGainDb < -24 ) || ( f_pVqeConfig->lRinLevelControlGainDb > 24 ) ) + return cOCT6100_ERR_CHANNEL_RIN_LEVEL_CONTROL_GAIN; + + if ( ( f_pVqeConfig->lSoutLevelControlGainDb < -24 ) || ( f_pVqeConfig->lSoutLevelControlGainDb > 24 ) ) + return cOCT6100_ERR_CHANNEL_SOUT_LEVEL_CONTROL_GAIN; + + if ( ( f_pVqeConfig->fRinAutomaticLevelControl != TRUE ) && ( f_pVqeConfig->fRinAutomaticLevelControl != FALSE ) ) + return cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_CONTROL; + + if ( ( f_pVqeConfig->fRinHighLevelCompensation != TRUE ) && ( f_pVqeConfig->fRinHighLevelCompensation != FALSE ) ) + return cOCT6100_ERR_CHANNEL_RIN_HIGH_LEVEL_COMP; + + if ( ( f_pVqeConfig->fRinAutomaticLevelControl == TRUE ) && ( pImageInfo->fRinAutoLevelControl == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_RIN_AUTO_LC; + + if ( ( f_pVqeConfig->fRinHighLevelCompensation == TRUE ) && ( pImageInfo->fRinHighLevelCompensation == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_RIN_HIGH_LEVEL_COMP; + + if ( f_pVqeConfig->fRinAutomaticLevelControl == TRUE ) + { + if ( f_pVqeConfig->fRinLevelControl == TRUE ) + return cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_MANUAL; + + if ( f_pVqeConfig->fRinHighLevelCompensation == TRUE ) + return cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_HIGH_LEVEL_COMP; + + if ( ( f_pVqeConfig->lRinAutomaticLevelControlTargetDb < -40 || f_pVqeConfig->lRinAutomaticLevelControlTargetDb > 0 ) ) + return cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_CONTROL_TARGET; + } + + if ( f_pVqeConfig->fRinHighLevelCompensation == TRUE ) + { + if ( f_pVqeConfig->fRinLevelControl == TRUE ) + return cOCT6100_ERR_CHANNEL_RIN_HIGH_LEVEL_COMP_MANUAL; + + if ( ( f_pVqeConfig->lRinHighLevelCompensationThresholdDb < -40 || f_pVqeConfig->lRinHighLevelCompensationThresholdDb > 0 ) ) + return cOCT6100_ERR_CHANNEL_RIN_HIGH_LEVEL_COMP_THRESHOLD; + } + + if ( f_pVqeConfig->fSoutAutomaticLevelControl != TRUE && f_pVqeConfig->fSoutAutomaticLevelControl != FALSE ) + return cOCT6100_ERR_CHANNEL_SOUT_AUTO_LEVEL_CONTROL; + + if ( ( f_pVqeConfig->fSoutAutomaticLevelControl == TRUE ) && ( pImageInfo->fSoutAutoLevelControl == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SOUT_AUTO_LC; + + if ( f_pVqeConfig->fSoutAutomaticLevelControl == TRUE ) + { + if ( f_pVqeConfig->fSoutLevelControl == TRUE ) + return cOCT6100_ERR_CHANNEL_SOUT_AUTO_LEVEL_MANUAL; + + if ( ( f_pVqeConfig->lSoutAutomaticLevelControlTargetDb < -40 || f_pVqeConfig->lSoutAutomaticLevelControlTargetDb > 0 ) ) + return cOCT6100_ERR_CHANNEL_SOUT_AUTO_LEVEL_CONTROL_TARGET; + } + + if ( f_pVqeConfig->fSoutAdaptiveNoiseReduction != TRUE && + f_pVqeConfig->fSoutAdaptiveNoiseReduction != FALSE ) + return cOCT6100_ERR_CHANNEL_SOUT_ADAPT_NOISE_REDUCTION; + + if ( f_pVqeConfig->fSoutAdaptiveNoiseReduction == TRUE && pImageInfo->fAdaptiveNoiseReduction == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ANR; + + if ( f_pVqeConfig->fSoutConferencingNoiseReduction != TRUE && + f_pVqeConfig->fSoutConferencingNoiseReduction != FALSE ) + return cOCT6100_ERR_CHANNEL_SOUT_CONFERENCE_NOISE_REDUCTION; + + if ( f_pVqeConfig->fSoutConferencingNoiseReduction == TRUE && pImageInfo->fConferencingNoiseReduction == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_CNR; + + /* Validate Sout noise bleaching parameter. */ + if ( f_pVqeConfig->fSoutNoiseBleaching != TRUE && + f_pVqeConfig->fSoutNoiseBleaching != FALSE ) + return cOCT6100_ERR_CHANNEL_SOUT_NOISE_BLEACHING; + + /* Check if firmware supports Sout noise bleaching. */ + if ( f_pVqeConfig->fSoutNoiseBleaching == TRUE && pImageInfo->fSoutNoiseBleaching == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NOISE_BLEACHING; + + /* If Sout noise bleaching is requested, no ANR or CNR shall be activated. */ + if ( f_pVqeConfig->fSoutNoiseBleaching == TRUE ) + { + /* No xNR! */ + if ( ( f_pVqeConfig->fSoutConferencingNoiseReduction == TRUE ) + || ( f_pVqeConfig->fSoutAdaptiveNoiseReduction == TRUE ) ) + return cOCT6100_ERR_CHANNEL_SOUT_NOISE_BLEACHING_NR; + } + + /* Cannot activate both ANR and CNR when noise bleaching is present */ + if ( pImageInfo->fSoutNoiseBleaching == TRUE ) + { + if ( f_pVqeConfig->fSoutAdaptiveNoiseReduction == TRUE && + f_pVqeConfig->fSoutConferencingNoiseReduction == TRUE ) + return cOCT6100_ERR_CHANNEL_ANR_CNR_SIMULTANEOUSLY; + } + + /* Validate the DTMF tone removal parameter.*/ + if ( f_pVqeConfig->fDtmfToneRemoval != TRUE && f_pVqeConfig->fDtmfToneRemoval != FALSE ) + return cOCT6100_ERR_CHANNEL_TONE_REMOVAL; + + if ( f_pVqeConfig->fDtmfToneRemoval == TRUE && pImageInfo->fToneRemoval == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TONE_REMOVAL; + + + + /* Check the Tail displacement enable.*/ + if ( f_pVqeConfig->fEnableTailDisplacement != TRUE && f_pVqeConfig->fEnableTailDisplacement != FALSE ) + return cOCT6100_ERR_CHANNEL_ENABLE_TAIL_DISPLACEMENT; + + if ( f_pVqeConfig->fEnableTailDisplacement == TRUE && pImageInfo->fTailDisplacement == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TAIL_DISPLACEMENT; + + /* Check the Tail displacement value.*/ + if ( f_pVqeConfig->fEnableTailDisplacement == TRUE ) + { + if ( f_pVqeConfig->ulTailDisplacement != cOCT6100_AUTO_SELECT_TAIL ) + { + /* Check if this feature is supported by the image. */ + if ( pImageInfo->fPerChannelTailDisplacement == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_PER_CHAN_TAIL; + + /* Check that this value is not greater then what the image supports. */ + if ( f_pVqeConfig->ulTailDisplacement > pImageInfo->usMaxTailDisplacement ) + return cOCT6100_ERR_CHANNEL_TAIL_DISPLACEMENT_INVALID; + } + } + + /* Check the tail length value. */ + if ( f_pVqeConfig->ulTailLength != cOCT6100_AUTO_SELECT_TAIL ) + { + /* Check if this feature is supported by the image. */ + if ( ( pImageInfo->fPerChannelTailLength == FALSE ) + && ( (UINT16)( f_pVqeConfig->ulTailLength & 0xFFFF ) != pImageInfo->usMaxTailLength ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TAIL_LENGTH; + + if ( ( f_pVqeConfig->ulTailLength < 32 ) || ( f_pVqeConfig->ulTailLength > 128 ) + || ( ( f_pVqeConfig->ulTailLength % 4 ) != 0x0 ) ) + return cOCT6100_ERR_CHANNEL_TAIL_LENGTH; + + /* Check if the requested tail length is supported by the chip. */ + if ( f_pVqeConfig->ulTailLength > pImageInfo->usMaxTailLength ) + return cOCT6100_ERR_CHANNEL_TAIL_LENGTH_INVALID; + } + + /* Validate the acoustic echo cancellation parameter.*/ + if ( f_pVqeConfig->fAcousticEcho != TRUE && f_pVqeConfig->fAcousticEcho != FALSE ) + return cOCT6100_ERR_CHANNEL_ACOUSTIC_ECHO; + + if ( f_pVqeConfig->fAcousticEcho == TRUE && pImageInfo->fAcousticEcho == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ACOUSTIC_ECHO; + + if ( f_pVqeConfig->fAcousticEcho == TRUE ) + { + /* Check if acoustic echo tail length configuration is supported in the image. */ + if ( ( f_pVqeConfig->ulAecTailLength != 128 ) && ( pImageInfo->fAecTailLength == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ACOUSTIC_ECHO_TAIL_LENGTH; + + /* Check the requested acoustic echo tail length. */ + if ( ( f_pVqeConfig->ulAecTailLength != 128 ) + && ( f_pVqeConfig->ulAecTailLength != 256 ) + && ( f_pVqeConfig->ulAecTailLength != 512 ) + && ( f_pVqeConfig->ulAecTailLength != 1024 ) ) + return cOCT6100_ERR_CHANNEL_ACOUSTIC_ECHO_TAIL_LENGTH; + + if ( f_pVqeConfig->fEnableTailDisplacement == TRUE ) + { + UINT32 ulTailSum; + + /* Start with requested tail displacement. */ + if ( f_pVqeConfig->ulTailDisplacement == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTailSum = f_pApiInstance->pSharedInfo->ChipConfig.usTailDisplacement; + } + else + { + ulTailSum = f_pVqeConfig->ulTailDisplacement; + } + + /* Add requested tail length. */ + if ( f_pVqeConfig->ulTailLength == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTailSum += f_pApiInstance->pSharedInfo->ImageInfo.usMaxTailLength; + } + else + { + ulTailSum += f_pVqeConfig->ulTailLength; + } + + /* The tail sum must be smaller then the requested AEC tail length. */ + if ( ulTailSum > f_pVqeConfig->ulAecTailLength ) + return cOCT6100_ERR_CHANNEL_ACOUSTIC_ECHO_TAIL_SUM; + } + } + + /* Validate the Default ERL parameter.*/ + if ( f_pVqeConfig->lDefaultErlDb != -6 && pImageInfo->fDefaultErl == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_DEFAULT_ERL; + + if ( ( f_pVqeConfig->lDefaultErlDb != 0 ) && + ( f_pVqeConfig->lDefaultErlDb != -3 ) && + ( f_pVqeConfig->lDefaultErlDb != -6 ) && + ( f_pVqeConfig->lDefaultErlDb != -9 ) && + ( f_pVqeConfig->lDefaultErlDb != -12 ) ) + return cOCT6100_ERR_CHANNEL_DEFAULT_ERL; + + /* Validate the Default AEC ERL parameter.*/ + if ( f_pVqeConfig->lAecDefaultErlDb != 0 && pImageInfo->fAecDefaultErl == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_AEC_DEFAULT_ERL; + + if ( f_pVqeConfig->lAecDefaultErlDb != 0 && f_pVqeConfig->lAecDefaultErlDb != -3 && f_pVqeConfig->lAecDefaultErlDb != -6 ) + return cOCT6100_ERR_CHANNEL_AEC_DEFAULT_ERL; + + /* Validate the non-linearity A parameter.*/ + if ( f_pVqeConfig->ulNonLinearityBehaviorA != 1 && pImageInfo->fNonLinearityBehaviorA == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_DOUBLE_TALK; + + if ( f_pVqeConfig->ulNonLinearityBehaviorA >= 14 ) + return cOCT6100_ERR_CHANNEL_DOUBLE_TALK; + + /* Validate the non-linearity B parameter.*/ + if ( f_pVqeConfig->ulNonLinearityBehaviorB != 0 && pImageInfo->fNonLinearityBehaviorB == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NON_LINEARITY_B; + + if ( f_pVqeConfig->ulNonLinearityBehaviorB >= 9 ) + return cOCT6100_ERR_CHANNEL_NON_LINEARITY_B; + + /* Check if configuring the double talk behavior is supported in the firmware. */ + if ( f_pVqeConfig->ulDoubleTalkBehavior != cOCT6100_DOUBLE_TALK_BEH_NORMAL && pImageInfo->fDoubleTalkBehavior == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_DOUBLE_TALK_BEHAVIOR_MODE; + + /* Validate the double talk behavior mode parameter. */ + if ( f_pVqeConfig->ulDoubleTalkBehavior != cOCT6100_DOUBLE_TALK_BEH_NORMAL && f_pVqeConfig->ulDoubleTalkBehavior != cOCT6100_DOUBLE_TALK_BEH_LESS_AGGRESSIVE ) + return cOCT6100_ERR_CHANNEL_DOUBLE_TALK_MODE; + + /* Validate the Sout automatic listener enhancement ratio. */ + if ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb != 0 && pImageInfo->fListenerEnhancement == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ALE; + + if ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb > 30 ) + return cOCT6100_ERR_CHANNEL_ALE_RATIO; + + /* Validate the Sout natural listener enhancement ratio. */ + if ( f_pVqeConfig->fSoutNaturalListenerEnhancement != TRUE && f_pVqeConfig->fSoutNaturalListenerEnhancement != FALSE ) + return cOCT6100_ERR_CHANNEL_NLE_FLAG; + + if ( f_pVqeConfig->fSoutNaturalListenerEnhancement == TRUE && pImageInfo->fListenerEnhancement == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NLE; + + if ( f_pVqeConfig->fSoutNaturalListenerEnhancement == TRUE ) + { + if ( f_pVqeConfig->ulSoutNaturalListenerEnhancementGainDb > 30 ) + return cOCT6100_ERR_CHANNEL_NLE_RATIO; + } + + /* Both ALE and NLE cannot be activated simultaneously. */ + if ( ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb != 0 ) + && ( f_pVqeConfig->fSoutNaturalListenerEnhancement == TRUE ) ) + return cOCT6100_ERR_CHANNEL_ALE_NLE_SIMULTANEOUSLY; + + /* Validate Rout noise reduction. */ + if ( f_pVqeConfig->fRoutNoiseReduction != TRUE && f_pVqeConfig->fRoutNoiseReduction != FALSE ) + return cOCT6100_ERR_CHANNEL_ROUT_NOISE_REDUCTION; + + /* Check if Rout noise reduction is supported. */ + if ( f_pVqeConfig->fRoutNoiseReduction == TRUE && pImageInfo->fRoutNoiseReduction == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ROUT_NR; + + /*Check if noise reduction level gain is supported*/ + if ( ( pImageInfo->fRoutNoiseReductionLevel == FALSE ) && ( f_pVqeConfig->lRoutNoiseReductionLevelGainDb != -18 ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ROUT_NOISE_REDUCTION_GAIN; + + if ( ( f_pVqeConfig->lRoutNoiseReductionLevelGainDb != 0 ) && + ( f_pVqeConfig->lRoutNoiseReductionLevelGainDb != -6 ) && + ( f_pVqeConfig->lRoutNoiseReductionLevelGainDb != -12 ) && + ( f_pVqeConfig->lRoutNoiseReductionLevelGainDb != -18 ) ) + + return cOCT6100_ERR_CHANNEL_ROUT_NOISE_REDUCTION_GAIN; + + /* Check if ANR SNRE is supported. */ + if ( ( f_pVqeConfig->lAnrSnrEnhancementDb != -18 ) && ( pImageInfo->fAnrSnrEnhancement == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ANR_SNR_ENHANCEMENT; + + /* Validate Sout ANR SNR enhancement. */ + if ( ( f_pVqeConfig->lAnrSnrEnhancementDb != -9 ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != -12 ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != -15 ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != -18 ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != -21 ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != -24 ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != -27 ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != -30 ) ) + return cOCT6100_ERR_CHANNEL_ANR_SNR_ENHANCEMENT; + + /* Validate ANR voice-noise segregation. */ + if ( f_pVqeConfig->ulAnrVoiceNoiseSegregation > 15 ) + return cOCT6100_ERR_CHANNEL_ANR_SEGREGATION; + + /* Check if ANR VN segregation is supported. */ + if ( ( f_pVqeConfig->ulAnrVoiceNoiseSegregation != 6 ) && ( pImageInfo->fAnrVoiceNoiseSegregation == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ANR_SEGREGATION; + + /* Check if the loaded image supports tone disabler VQE activation delay. */ + if ( ( f_pVqeConfig->ulToneDisablerVqeActivationDelay != 300 ) + && ( pImageInfo->fToneDisablerVqeActivationDelay == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TONE_DISABLER_ACTIVATION_DELAY; + + /* Check if the specified tone disabler VQE activation delay is correct. */ + if ( ( f_pVqeConfig->ulToneDisablerVqeActivationDelay < 300 ) + || ( ( ( f_pVqeConfig->ulToneDisablerVqeActivationDelay - 300 ) % 512 ) != 0 ) ) + return cOCT6100_ERR_CHANNEL_TONE_DISABLER_ACTIVATION_DELAY; + + /* Check the enable music protection flag. */ + if ( ( f_pVqeConfig->fEnableMusicProtection != TRUE ) && ( f_pVqeConfig->fEnableMusicProtection != FALSE ) ) + return cOCT6100_ERR_CHANNEL_ENABLE_MUSIC_PROTECTION; + + /* The music protection module can only be activated if the image supports it. */ + if ( ( f_pVqeConfig->fEnableMusicProtection == TRUE ) && + ( pImageInfo->fMusicProtection == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_MUSIC_PROTECTION; + + /* Check the enable idle code detection flag. */ + if ( ( f_pVqeConfig->fIdleCodeDetection != TRUE ) && ( f_pVqeConfig->fIdleCodeDetection != FALSE ) ) + return cOCT6100_ERR_CHANNEL_IDLE_CODE_DETECTION; + + /* The idle code detection module can only be activated if the image supports it. */ + if ( ( f_pVqeConfig->fIdleCodeDetection == TRUE ) && ( pImageInfo->fIdleCodeDetection == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_IDLE_CODE_DETECTION; + + /* The idle code detection module can be disabled only if idle code detection configuration */ + /* is supported in the image. */ + if ( pImageInfo->fIdleCodeDetection == TRUE ) + { + if ( ( f_pVqeConfig->fIdleCodeDetection == FALSE ) && ( pImageInfo->fIdleCodeDetectionConfiguration == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_IDLE_CODE_DETECTION_CONFIG; + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckCodecConfig + +Description: This function will check the validity of the Codec config parameter + of an Open Codec config structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pCodecConfig Codec config of the channel. +f_ulDecoderNumTssts Number of TSST for the decoder. +f_pusPhasingTsstIndex Pointer to the Phasing TSST index within the API's phasing TSST list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckCodecConfig +UINT32 Oct6100ApiCheckCodecConfig( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_CODEC f_pCodecConfig, + IN UINT32 f_ulDecoderNumTssts, + OUT PUINT16 f_pusPhasingTsstIndex ) +{ + + /* Verify the ADPCM nibble value.*/ + if ( f_pCodecConfig->ulAdpcmNibblePosition != cOCT6100_ADPCM_IN_LOW_BITS && + f_pCodecConfig->ulAdpcmNibblePosition != cOCT6100_ADPCM_IN_HIGH_BITS ) + return cOCT6100_ERR_CHANNEL_ADPCM_NIBBLE; + + /* Verify the Encoder port.*/ + if ( f_pCodecConfig->ulEncoderPort != cOCT6100_CHANNEL_PORT_ROUT && + f_pCodecConfig->ulEncoderPort != cOCT6100_CHANNEL_PORT_SOUT && + f_pCodecConfig->ulEncoderPort != cOCT6100_NO_ENCODING ) + return cOCT6100_ERR_CHANNEL_ENCODER_PORT; + + /* Verify the Decoder port.*/ + if ( f_pCodecConfig->ulDecoderPort != cOCT6100_CHANNEL_PORT_RIN && + f_pCodecConfig->ulDecoderPort != cOCT6100_CHANNEL_PORT_SIN && + f_pCodecConfig->ulDecoderPort != cOCT6100_NO_DECODING ) + return cOCT6100_ERR_CHANNEL_DECODER_PORT; + + /* The codec cannot be on the same stream.*/ + if ( f_pCodecConfig->ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT && + f_pCodecConfig->ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + return cOCT6100_ERR_CHANNEL_INVALID_CODEC_POSITION; + + if ( f_pCodecConfig->ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT && + f_pCodecConfig->ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN ) + return cOCT6100_ERR_CHANNEL_INVALID_CODEC_POSITION; + + /* Verify if the requested functions are supported by the chip.*/ + if ( f_pApiInstance->pSharedInfo->ImageInfo.fAdpcm == FALSE && + f_pCodecConfig->ulEncoderPort != cOCT6100_NO_ENCODING ) + { + if ( f_pCodecConfig->ulEncodingRate != cOCT6100_G711_64KBPS ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ENCODING; + } + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fAdpcm == FALSE && + f_pCodecConfig->ulDecoderPort != cOCT6100_NO_DECODING ) + { + if ( f_pCodecConfig->ulDecodingRate != cOCT6100_G711_64KBPS ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_DECODING; + } + + /* Check if encoder port has been specified when a rate has been set. */ + if ( f_pCodecConfig->ulEncoderPort == cOCT6100_NO_ENCODING && + f_pCodecConfig->ulEncodingRate != cOCT6100_G711_64KBPS ) + return cOCT6100_ERR_CHANNEL_ENCODER_PORT; + + /* Check if decoder port has been specified when a rate has been set. */ + if ( f_pCodecConfig->ulDecoderPort == cOCT6100_NO_DECODING && + f_pCodecConfig->ulDecodingRate != cOCT6100_G711_64KBPS ) + return cOCT6100_ERR_CHANNEL_DECODER_PORT; + + /* Check Encoder related parameter if one is used.*/ + if ( f_pCodecConfig->ulEncoderPort != cOCT6100_NO_ENCODING ) + { + /* Check the Encoder compression rate.*/ + if ( ( f_pCodecConfig->ulEncodingRate != cOCT6100_G711_64KBPS ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G726_40KBPS ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G726_32KBPS ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G726_24KBPS ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G726_16KBPS ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_40KBPS_4_1 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_40KBPS_3_2 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_40KBPS_2_3 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_32KBPS_4_0 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_32KBPS_3_1 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_32KBPS_2_2 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_24KBPS_3_0 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_24KBPS_2_1 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_16KBPS_2_0 ) ) + return cOCT6100_ERR_CHANNEL_ENCODING_RATE; + + /* Verify phasing information.*/ + if ( f_pCodecConfig->ulPhasingType != cOCT6100_SINGLE_PHASING && + f_pCodecConfig->ulPhasingType != cOCT6100_DUAL_PHASING && + f_pCodecConfig->ulPhasingType != cOCT6100_NO_PHASING ) + return cOCT6100_ERR_CHANNEL_PHASING_TYPE; + + /* Verify the silence suppression parameters.*/ + if ( f_pCodecConfig->fEnableSilenceSuppression != TRUE && + f_pCodecConfig->fEnableSilenceSuppression != FALSE ) + return cOCT6100_ERR_CHANNEL_SIL_SUP_ENABLE; + + if ( f_pCodecConfig->fEnableSilenceSuppression == TRUE && + f_pApiInstance->pSharedInfo->ImageInfo.fSilenceSuppression == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SIL_SUP; + + if ( f_pCodecConfig->fEnableSilenceSuppression == TRUE && + f_pCodecConfig->ulPhasingType == cOCT6100_NO_PHASING ) + return cOCT6100_ERR_CHANNEL_PHASE_TYPE_REQUIRED; + + if ( f_pCodecConfig->fEnableSilenceSuppression == TRUE && + f_pCodecConfig->ulPhasingTsstHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_CHANNEL_PHASING_TSST_REQUIRED; + + if ( f_pCodecConfig->ulPhasingTsstHndl == cOCT6100_INVALID_HANDLE && + f_pCodecConfig->ulPhasingType != cOCT6100_NO_PHASING ) + return cOCT6100_ERR_CHANNEL_PHASING_TSST_REQUIRED; + + /* Silence suppression can only be performed if the encoder is using the SOUT port.*/ + if ( f_pCodecConfig->fEnableSilenceSuppression == TRUE && + f_pCodecConfig->ulEncoderPort != cOCT6100_CHANNEL_PORT_SOUT ) + return cOCT6100_ERR_CHANNEL_SIL_SUP_INVALID_ENCODER_PORT; + + /* Check phasing TSST info if phasing is required.*/ + if ( f_pCodecConfig->ulPhasingTsstHndl != cOCT6100_INVALID_HANDLE ) + { + tPOCT6100_API_PHASING_TSST pPhasingEntry; + UINT32 ulEntryOpenCnt; + + /* Check the provided handle. */ + if ( (f_pCodecConfig->ulPhasingTsstHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_PHASING_TSST ) + return cOCT6100_ERR_CHANNEL_INVALID_PHASING_HANDLE; + + *f_pusPhasingTsstIndex = (UINT16)( f_pCodecConfig->ulPhasingTsstHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusPhasingTsstIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxPhasingTssts ) + return cOCT6100_ERR_CHANNEL_INVALID_PHASING_HANDLE; + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPhasingEntry, *f_pusPhasingTsstIndex ); + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pCodecConfig->ulPhasingTsstHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Verify if the state of the phasing TSST.*/ + if ( pPhasingEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_PHASING_TSST_NOT_OPEN; + if ( ulEntryOpenCnt != pPhasingEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_PHASING_HANDLE; + + /* Check the specified phase value against the phasing length of the phasing TSST.*/ + if ( ( f_pCodecConfig->ulPhase == 0 ) + || ( f_pCodecConfig->ulPhase >= pPhasingEntry->usPhasingLength ) ) + return cOCT6100_ERR_CHANNEL_PHASING_INVALID_PHASE; + } + else + { + *f_pusPhasingTsstIndex = cOCT6100_INVALID_INDEX; + } + } + else + { + *f_pusPhasingTsstIndex = cOCT6100_INVALID_INDEX; + } + + + /* Check Decoder related parameter if one is used.*/ + if ( f_pCodecConfig->ulDecoderPort != cOCT6100_NO_DECODING ) + { + /* Check the Decoding rate.*/ + if ( f_pCodecConfig->ulDecodingRate != cOCT6100_G711_64KBPS && + f_pCodecConfig->ulDecodingRate != cOCT6100_G726_40KBPS && + f_pCodecConfig->ulDecodingRate != cOCT6100_G726_32KBPS && + f_pCodecConfig->ulDecodingRate != cOCT6100_G726_24KBPS && + f_pCodecConfig->ulDecodingRate != cOCT6100_G726_16KBPS && + f_pCodecConfig->ulDecodingRate != cOCT6100_G726_ENCODED && + f_pCodecConfig->ulDecodingRate != cOCT6100_G711_G726_ENCODED && + f_pCodecConfig->ulDecodingRate != cOCT6100_G727_2C_ENCODED && + f_pCodecConfig->ulDecodingRate != cOCT6100_G727_3C_ENCODED && + f_pCodecConfig->ulDecodingRate != cOCT6100_G727_4C_ENCODED && + f_pCodecConfig->ulDecodingRate != cOCT6100_G711_G727_2C_ENCODED && + f_pCodecConfig->ulDecodingRate != cOCT6100_G711_G727_3C_ENCODED && + f_pCodecConfig->ulDecodingRate != cOCT6100_G711_G727_4C_ENCODED ) + return cOCT6100_ERR_CHANNEL_DECODING_RATE; + + /* Make sure that two timeslot are allocated if PCM-ECHO encoded is selected.*/ + if ( (f_pCodecConfig->ulDecodingRate == cOCT6100_G711_G726_ENCODED || + f_pCodecConfig->ulDecodingRate == cOCT6100_G711_G727_2C_ENCODED || + f_pCodecConfig->ulDecodingRate == cOCT6100_G711_G727_3C_ENCODED || + f_pCodecConfig->ulDecodingRate == cOCT6100_G711_G727_4C_ENCODED ) && + f_ulDecoderNumTssts != 2 ) + return cOCT6100_ERR_CHANNEL_MISSING_TSST; + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteInputTsstControlMemory + +Description: This function configure a TSST control memory entry in internal memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usTsstIndex TSST index within the TSST control memory. +f_usTsiMemIndex TSI index within the TSI chariot memory. +f_ulTsstInputLaw PCM law of the input TSST. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteInputTsstControlMemory +UINT32 Oct6100ApiWriteInputTsstControlMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsstIndex, + IN UINT16 f_usTsiMemIndex, + IN UINT32 f_ulTsstInputLaw ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (f_usTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_TSST_CONTROL_MEM_INPUT_TSST; + WriteParams.usWriteData |= f_usTsiMemIndex & cOCT6100_TSST_CONTROL_MEM_TSI_MEM_MASK; + + /* Set the PCM law.*/ + WriteParams.usWriteData |= f_ulTsstInputLaw << cOCT6100_TSST_CONTROL_MEM_PCM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteOutputTsstControlMemory + +Description: This function configure a TSST control memory entry in internal memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteOutputTsstControlMemory +UINT32 Oct6100ApiWriteOutputTsstControlMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsstIndex, + IN UINT32 f_ulAdpcmNibblePosition, + IN UINT32 f_ulNumTssts, + IN UINT16 f_usTsiMemIndex ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (f_usTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_TSST_CONTROL_MEM_OUTPUT_TSST; + WriteParams.usWriteData |= f_ulAdpcmNibblePosition << cOCT6100_TSST_CONTROL_MEM_NIBBLE_POS_OFFSET; + WriteParams.usWriteData |= (f_ulNumTssts - 1) << cOCT6100_TSST_CONTROL_MEM_TSST_NUM_OFFSET; + WriteParams.usWriteData |= f_usTsiMemIndex & cOCT6100_TSST_CONTROL_MEM_TSI_MEM_MASK; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteEncoderMemory + +Description: This function configure a Encoded memory entry in internal memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulEncoderIndex Index of the encoder block within the ADPCM context memory. +f_ulCompType Compression rate of the encoder. +f_usTsiMemIndex TSI index within the TSI chariot memory used by the encoder. +f_ulEnableSilenceSuppression Silence suppression enable flag. +f_ulAdpcmNibblePosition ADPCM nibble position. +f_usPhasingTsstIndex Phasing TSST index within the API's Phassing TSST list. +f_ulPhasingType Type of the Phasing TSST. +f_ulPhase Phase used with this encoder. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteEncoderMemory +UINT32 Oct6100ApiWriteEncoderMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulEncoderIndex, + IN UINT32 f_ulCompType, + IN UINT16 f_usTsiMemIndex, + IN UINT32 f_ulEnableSilenceSuppression, + IN UINT32 f_ulAdpcmNibblePosition, + IN UINT16 f_usPhasingTsstIndex, + IN UINT32 f_ulPhasingType, + IN UINT32 f_ulPhase ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /*==============================================================================*/ + /* Conversion Control Base */ + WriteParams.ulWriteAddress = cOCT6100_CONVERSION_CONTROL_MEM_BASE + ( f_ulEncoderIndex * cOCT6100_CONVERSION_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_CONVERSION_CONTROL_MEM_ENCODER; + WriteParams.usWriteData |= f_ulCompType << cOCT6100_CONVERSION_CONTROL_MEM_COMP_OFFSET; + WriteParams.usWriteData |= f_usTsiMemIndex & cOCT6100_TSST_CONTROL_MEM_TSI_MEM_MASK; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + /* Conversion Control Base + 2 */ + WriteParams.ulWriteAddress += 2; + + /* Set the phasing TSST number.*/ + if ( f_usPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + WriteParams.usWriteData = (UINT16)( f_usPhasingTsstIndex << cOCT6100_CONVERSION_CONTROL_MEM_PHASE_OFFSET ); + else + WriteParams.usWriteData = 0; + + /* Set the phasing type and the phase value if required.*/ + switch( f_ulPhasingType ) + { + case cOCT6100_NO_PHASING: + WriteParams.usWriteData |= 0x1 << 10; + break; + case cOCT6100_SINGLE_PHASING: + WriteParams.usWriteData |= f_ulPhase; + break; + case cOCT6100_DUAL_PHASING: + WriteParams.usWriteData |= 0x1 << 11; + WriteParams.usWriteData |= f_ulPhase; + break; + default: + /* No problem. */ + break; + } + + /* Set the silence suppression flag.*/ + WriteParams.usWriteData |= f_ulEnableSilenceSuppression << cOCT6100_CONVERSION_CONTROL_MEM_SIL_SUP_OFFSET; + + /* Set the nibble position.*/ + WriteParams.usWriteData |= f_ulAdpcmNibblePosition << cOCT6100_CONVERSION_CONTROL_MEM_NIBBLE_POS_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + /* Conversion Control Base + 4 */ + WriteParams.ulWriteAddress += 2; + + /* Set the reset mode */ + WriteParams.usWriteData = cOCT6100_CONVERSION_CONTROL_MEM_RST_ON_NEXT_FR; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + /* Conversion Control Base + 6 */ + WriteParams.ulWriteAddress += 2; + + /* Set the reset mode */ + WriteParams.usWriteData = cOCT6100_CONVERSION_CONTROL_MEM_ACTIVATE_ENTRY; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteDecoderMemory + +Description: This function configure a Decoder memory entry in internal memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usDecoderIndex Index of the decoder block within the ADPCM context memory. +f_ulCompType Decompression rate of the decoder. +f_usTsiMemIndex TSI index within the TSI chariot memory. +f_ulPcmLaw PCM law of the decoded samples. +f_ulAdpcmNibblePosition ADPCM nibble position. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteDecoderMemory +UINT32 Oct6100ApiWriteDecoderMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usDecoderIndex, + IN UINT32 f_ulCompType, + IN UINT16 f_usTsiMemIndex, + IN UINT32 f_ulPcmLaw, + IN UINT32 f_ulAdpcmNibblePosition ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + + /*==============================================================================*/ + /* Conversion Control Base */ + WriteParams.ulWriteAddress = cOCT6100_CONVERSION_CONTROL_MEM_BASE + ( f_usDecoderIndex * cOCT6100_CONVERSION_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_CONVERSION_CONTROL_MEM_DECODER; + WriteParams.usWriteData |= f_ulCompType << cOCT6100_CONVERSION_CONTROL_MEM_COMP_OFFSET; + WriteParams.usWriteData |= f_usTsiMemIndex & cOCT6100_TSST_CONTROL_MEM_TSI_MEM_MASK; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + /* Conversion Control Base + 2 */ + WriteParams.ulWriteAddress += 2; + + /* Set the nibble position.*/ + WriteParams.usWriteData = (UINT16)( f_ulAdpcmNibblePosition << cOCT6100_CONVERSION_CONTROL_MEM_NIBBLE_POS_OFFSET ); + + /* Set the law.*/ + WriteParams.usWriteData |= f_ulPcmLaw << cOCT6100_CONVERSION_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + /* Conversion Control Base + 4 */ + WriteParams.ulWriteAddress += 2; + + /* Set the reset mode */ + WriteParams.usWriteData = cOCT6100_CONVERSION_CONTROL_MEM_RST_ON_NEXT_FR; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + /* Conversion Control Base + 6 */ + WriteParams.ulWriteAddress += 2; + + /* Set the reset mode */ + WriteParams.usWriteData = cOCT6100_CONVERSION_CONTROL_MEM_ACTIVATE_ENTRY; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiClearConversionMemory + +Description: This function clears a conversion memory entry in internal + memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usConversionMemIndex Index of the block within the conversion memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiClearConversionMemory +UINT32 Oct6100ApiClearConversionMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usConversionMemIndex ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT32 ulBaseAddress; + UINT16 usReadData; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + WriteParams.usWriteData = 0; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /*==============================================================================*/ + /* Clear the entry */ + ulBaseAddress = cOCT6100_CONVERSION_CONTROL_MEM_BASE + ( f_usConversionMemIndex * cOCT6100_CONVERSION_CONTROL_MEM_ENTRY_SIZE ); + /* The "activate" bit at offset +6 must be cleared first. */ + WriteParams.ulWriteAddress = ulBaseAddress + 6; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Read at 0x200 to make sure there is no corruption on channel 0. */ + ReadParams.ulReadAddress = 0x200; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Then clear the rest of the structure. */ + WriteParams.ulWriteAddress = ulBaseAddress + 4; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = ulBaseAddress + 2; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = ulBaseAddress; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteVqeMemory + +Description: This function configure an echo memory entry in internal memory and + external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pVqeConfig Pointer to a VQE config structure. +f_pChannelOpen Pointer to a channel configuration structure. +f_usChanIndex Index of the echo channel in the API instance. +f_usEchoMemIndex Index of the echo channel within the SSPX memory. +f_fClearPlayoutPointers Flag indicating if the playout pointer should be cleared. +f_fModifyOnly Flag indicating if the configuration should be + modified only. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteVqeMemory +UINT32 Oct6100ApiWriteVqeMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fClearPlayoutPointers, + IN BOOL f_fModifyOnly ) +{ + UINT32 ulResult; + + /* Write the NLP software configuration structure. */ + ulResult = Oct6100ApiWriteVqeNlpMemory( + f_pApiInstance, + f_pVqeConfig, + f_pChannelOpen, + f_usChanIndex, + f_usEchoMemIndex, + f_fClearPlayoutPointers, + f_fModifyOnly ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write the AF software configuration structure. */ + ulResult = Oct6100ApiWriteVqeAfMemory( + f_pApiInstance, + f_pVqeConfig, + f_pChannelOpen, + f_usChanIndex, + f_usEchoMemIndex, + f_fClearPlayoutPointers, + f_fModifyOnly ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +UINT32 oct6100_retrieve_nlp_conf_dword(tPOCT6100_INSTANCE_API f_pApiInst, + tPOCT6100_API_CHANNEL f_pChanEntry, + UINT32 f_ulAddress, + UINT32 *f_pulConfigDword) +{ + tOCT6100_READ_PARAMS _ReadParams; + UINT16 _usReadData; + UINT32 ulResult = cOCT6100_ERR_FATAL_8E; + (*f_pulConfigDword) = cOCT6100_INVALID_VALUE; + + _ReadParams.pProcessContext = f_pApiInst->pProcessContext; + mOCT6100_ASSIGN_USER_READ_WRITE_OBJ(f_pApiInst, _ReadParams); + _ReadParams.ulUserChipId = f_pApiInst->pSharedInfo->ChipConfig.ulUserChipId; + _ReadParams.pusReadData = &_usReadData; + + /* Read the first 16 bits.*/ + _ReadParams.ulReadAddress = f_ulAddress; + mOCT6100_DRIVER_READ_API(_ReadParams, ulResult); + if (ulResult == cOCT6100_ERR_OK) { + /* Save data.*/ + (*f_pulConfigDword) = _usReadData << 16; + + /* Read the last 16 bits .*/ + _ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API(_ReadParams, ulResult); + if (ulResult == cOCT6100_ERR_OK) { + /* Save data.*/ + (*f_pulConfigDword) |= _usReadData; + ulResult = cOCT6100_ERR_OK; + } + } + return ulResult; +} + +UINT32 oct6100_save_nlp_conf_dword(tPOCT6100_INSTANCE_API f_pApiInst, + tPOCT6100_API_CHANNEL f_pChanEntry, + UINT32 f_ulAddress, + UINT32 f_ulConfigDword) +{ + UINT32 ulResult; + + /* Write the config DWORD. */ + tOCT6100_WRITE_PARAMS _WriteParams; + + _WriteParams.pProcessContext = f_pApiInst->pProcessContext; + mOCT6100_ASSIGN_USER_READ_WRITE_OBJ(f_pApiInst, _WriteParams) + _WriteParams.ulUserChipId = f_pApiInst->pSharedInfo->ChipConfig.ulUserChipId; + + /* Write the first 16 bits. */ + _WriteParams.ulWriteAddress = f_ulAddress; + _WriteParams.usWriteData = (UINT16)((f_ulConfigDword >> 16) & 0xFFFF); + mOCT6100_DRIVER_WRITE_API(_WriteParams, ulResult); + + if (ulResult == cOCT6100_ERR_OK) { + /* Write the last word. */ + _WriteParams.ulWriteAddress = f_ulAddress + 2; + _WriteParams.usWriteData = (UINT16)(f_ulConfigDword & 0xFFFF); + mOCT6100_DRIVER_WRITE_API(_WriteParams, ulResult); + } + return ulResult; +} + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteVqeNlpMemory + +Description: This function configures the NLP related VQE features of an + echo channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pVqeConfig Pointer to a VQE config structure. +f_pChannelOpen Pointer to a channel configuration structure. +f_usChanIndex Index of the echo channel in the API instance. +f_usEchoMemIndex Index of the echo channel within the SSPX memory. +f_fClearPlayoutPointers Flag indicating if the playout pointer should be cleared. +f_fModifyOnly Flag indicating if the configuration should be + modified only. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteVqeNlpMemory +UINT32 Oct6100ApiWriteVqeNlpMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fClearPlayoutPointers, + IN BOOL f_fModifyOnly ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_BUFFER_PLAYOUT_STOP BufferPlayoutStop; + UINT32 ulResult; + UINT32 ulTempData; + UINT32 ulNlpConfigBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulMask; + UINT16 usTempData; + BOOL fEchoOperationModeChanged; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ); + + /*==============================================================================*/ + /* Configure the CPU NLP configuration of the channel feature by feature.*/ + + ulNlpConfigBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + + /* Set initial value to zero.*/ + ulTempData = 0; + + /* Configure Adaptive Noise Reduction.*/ + if (pSharedInfo->ImageInfo.fAdaptiveNoiseReduction == TRUE) { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->fSoutAdaptiveNoiseReduction != pChanEntry->VqeConfig.fSoutAdaptiveNoiseReduction ) + || ( f_pVqeConfig->fSoutNoiseBleaching != pChanEntry->VqeConfig.fSoutNoiseBleaching ) + ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AdaptiveNoiseReductionOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AdaptiveNoiseReductionOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AdaptiveNoiseReductionOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set adaptive noise reduction on the SOUT port.*/ + ulTempData |= ( ( (UINT32)f_pVqeConfig->fSoutAdaptiveNoiseReduction ) << ulFeatureBitOffset ); + + /* If SOUT noise bleaching is requested, ANR must be activated. */ + ulTempData |= ( ( (UINT32)f_pVqeConfig->fSoutNoiseBleaching ) << ulFeatureBitOffset ); + + /* First read the DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Configure Rout Noise Reduction. */ + if (pSharedInfo->ImageInfo.fRoutNoiseReduction == TRUE) { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fRoutNoiseReduction != pChanEntry->VqeConfig.fRoutNoiseReduction ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.RinAnrOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.RinAnrOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.RinAnrOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set noise reduction on the Rout port. */ + ulTempData |= ( ( (UINT32)f_pVqeConfig->fRoutNoiseReduction ) << ulFeatureBitOffset ); + + /* Write the new DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + if (pSharedInfo->ImageInfo.fRoutNoiseReductionLevel == TRUE) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( (f_pVqeConfig->lRoutNoiseReductionLevelGainDb != pChanEntry->VqeConfig.chRoutNoiseReductionLevelGainDb ) + ||( f_pVqeConfig->fRoutNoiseReduction != pChanEntry->VqeConfig.fRoutNoiseReduction ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.RinAnrValOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.RinAnrValOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.RinAnrValOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if (f_pVqeConfig->fRoutNoiseReduction == TRUE) + { + switch( f_pVqeConfig->lRoutNoiseReductionLevelGainDb) + { + case 0: ulTempData |= ( 0 << ulFeatureBitOffset ); + break; + case -6: ulTempData |= ( 1 << ulFeatureBitOffset ); + break; + case -12: ulTempData |= ( 2 << ulFeatureBitOffset ); + break; + case -18: ulTempData |= ( 3 << ulFeatureBitOffset ); + break; + default: ulTempData |= ( 0 << ulFeatureBitOffset ); + break; + } + } + else + ulTempData |= ( 0 << ulFeatureBitOffset ); + + /* Write the new DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + } + + /* Configure Sout ANR SNR enhancement. */ + if ( pSharedInfo->ImageInfo.fAnrSnrEnhancement == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != pChanEntry->VqeConfig.chAnrSnrEnhancementDb ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AnrSnrEnhancementOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AnrSnrEnhancementOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AnrSnrEnhancementOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set ANR SNR enhancement on the Sout port. */ + switch( f_pVqeConfig->lAnrSnrEnhancementDb ) + { + case -9: ulTempData |= ( 7 << ulFeatureBitOffset ); + break; + case -12: ulTempData |= ( 6 << ulFeatureBitOffset ); + break; + case -15: ulTempData |= ( 5 << ulFeatureBitOffset ); + break; + case -21: ulTempData |= ( 3 << ulFeatureBitOffset ); + break; + case -24: ulTempData |= ( 2 << ulFeatureBitOffset ); + break; + case -27: ulTempData |= ( 1 << ulFeatureBitOffset ); + break; + case -30: ulTempData |= ( 0 << ulFeatureBitOffset ); + break; + default: ulTempData |= ( 4 << ulFeatureBitOffset ); + /* -18 */ + break; + } + + /* Write the new DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Configure Sout ANR voice-noise segregation. */ + if ( pSharedInfo->ImageInfo.fAnrVoiceNoiseSegregation == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->ulAnrVoiceNoiseSegregation != pChanEntry->VqeConfig.byAnrVoiceNoiseSegregation ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AnrVoiceNoiseSegregationOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AnrVoiceNoiseSegregationOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AnrVoiceNoiseSegregationOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set ANR voice-noise segregation on the Sout port. */ + ulTempData |= ( ( (UINT32)f_pVqeConfig->ulAnrVoiceNoiseSegregation ) << ulFeatureBitOffset ); + + /* Write the new DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Configure the tone disabler VQE activation delay. */ + if ( pSharedInfo->ImageInfo.fToneDisablerVqeActivationDelay == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->ulToneDisablerVqeActivationDelay != pChanEntry->VqeConfig.usToneDisablerVqeActivationDelay ) + || ( f_pChannelOpen->fEnableToneDisabler != pChanEntry->fEnableToneDisabler ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.ToneDisablerVqeActivationDelayOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.ToneDisablerVqeActivationDelayOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.ToneDisablerVqeActivationDelayOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set the tone disabler VQE activation delay. The VQE activation delay */ + /* is only set if the tone disabler is activated. */ + if ( f_pChannelOpen->fEnableToneDisabler == TRUE ) + ulTempData |= ( ( (UINT32)( ( f_pVqeConfig->ulToneDisablerVqeActivationDelay - 300 ) / 512 ) ) << ulFeatureBitOffset ); + else + ulTempData |= ( 0 ) << ulFeatureBitOffset; + + /* Write the new DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Configure Conferencing Noise Reduction.*/ + if ( pSharedInfo->ImageInfo.fConferencingNoiseReduction == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->fSoutConferencingNoiseReduction != pChanEntry->VqeConfig.fSoutConferencingNoiseReduction ) + || ( f_pVqeConfig->fSoutNoiseBleaching != pChanEntry->VqeConfig.fSoutNoiseBleaching ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.ConferencingNoiseReductionOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.ConferencingNoiseReductionOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.ConferencingNoiseReductionOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set conferencing noise reduction on the SOUT port. */ + ulTempData |= (f_pVqeConfig->fSoutConferencingNoiseReduction << ulFeatureBitOffset ); + + /* If SOUT noise bleaching is requested, CNR must be activated. */ + ulTempData |= (f_pVqeConfig->fSoutNoiseBleaching << ulFeatureBitOffset ); + + /* Save the DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the DC removal on RIN ports.*/ + if ( pSharedInfo->ImageInfo.fRinDcOffsetRemoval == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fRinDcOffsetRemoval != pChanEntry->VqeConfig.fRinDcOffsetRemoval ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.RinDcOffsetRemovalOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.RinDcOffsetRemovalOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.RinDcOffsetRemovalOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set adaptive noise reduction on the SOUT port.*/ + ulTempData |= ( ( (UINT32)f_pVqeConfig->fRinDcOffsetRemoval ) << ulFeatureBitOffset ); + + /* The write the new DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the DC removal on SIN ports.*/ + if ( pSharedInfo->ImageInfo.fSinDcOffsetRemoval == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fSinDcOffsetRemoval != pChanEntry->VqeConfig.fSinDcOffsetRemoval ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.SinDcOffsetRemovalOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.SinDcOffsetRemovalOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.SinDcOffsetRemovalOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set adaptive noise reduction on the SOUT port.*/ + ulTempData |= ( ( (UINT32)f_pVqeConfig->fSinDcOffsetRemoval ) << ulFeatureBitOffset ); + + /* Save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the level control. */ + if ( ( pChanEntry->byEchoOperationMode != f_pChannelOpen->ulEchoOperationMode ) + && ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_NORMAL ) ) + fEchoOperationModeChanged = TRUE; + else + fEchoOperationModeChanged = FALSE; + + /* If opening the channel, all level control configuration must be written. */ + if ( f_fModifyOnly == FALSE ) + fEchoOperationModeChanged = TRUE; + ulResult = Oct6100ApiSetChannelLevelControl( f_pApiInstance, + f_pVqeConfig, + f_usChanIndex, + f_usEchoMemIndex, + fEchoOperationModeChanged ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the background noise freeze.*/ + if ( pSharedInfo->ImageInfo.fComfortNoise == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->ulComfortNoiseMode != pChanEntry->VqeConfig.byComfortNoiseMode ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.ComfortNoiseModeOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.ComfortNoiseModeOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.ComfortNoiseModeOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + ulTempData |= ( f_pVqeConfig->ulComfortNoiseMode << ulFeatureBitOffset ); + + /* Save the new DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the state of the NLP */ + if ( pSharedInfo->ImageInfo.fNlpControl == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fEnableNlp != pChanEntry->VqeConfig.fEnableNlp ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.NlpControlFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.NlpControlFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.NlpControlFieldOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( f_pVqeConfig->fEnableNlp == FALSE ) + ulTempData |= 0x1 << ulFeatureBitOffset; + + /* Save the new DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the tail configuration. */ + ulResult = Oct6100ApiSetChannelTailConfiguration( + f_pApiInstance, + f_pVqeConfig, + f_usChanIndex, + f_usEchoMemIndex, + f_fModifyOnly ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the Default ERL. */ + if ( ( pSharedInfo->ImageInfo.fDefaultErl == TRUE ) && ( f_pVqeConfig->fAcousticEcho == FALSE ) ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->lDefaultErlDb != pChanEntry->VqeConfig.chDefaultErlDb ) + || ( f_pChannelOpen->ulEchoOperationMode != pChanEntry->byEchoOperationMode ) + || ( f_pVqeConfig->fAcousticEcho != pChanEntry->VqeConfig.fAcousticEcho ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.DefaultErlFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.DefaultErlFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.DefaultErlFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Convert the DB value to octasic's float format. (In energy) */ + if ( ( f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_NO_ECHO ) + && ( f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) ) + { + usTempData = Oct6100ApiDbAmpHalfToOctFloat( 2 * f_pVqeConfig->lDefaultErlDb ); + } + else + { + /* Clear the defautl ERL when using the no echo cancellation operation mode. */ + usTempData = 0x0; + } + + if ( ulFeatureFieldLength < 16 ) + usTempData = (UINT16)( usTempData >> ( 16 - ulFeatureFieldLength ) ); + + ulTempData |= ( usTempData << ulFeatureBitOffset ); + + /* Save the new DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the Acoustic echo control.*/ + if ( pSharedInfo->ImageInfo.fAcousticEcho == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fAcousticEcho != pChanEntry->VqeConfig.fAcousticEcho ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AecFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AecFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AecFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field. */ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + ulTempData |= ( ( (UINT32)f_pVqeConfig->fAcousticEcho ) << ulFeatureBitOffset ); + + /* Then save the new DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the Acoustic Echo Default ERL. */ + if ( ( pSharedInfo->ImageInfo.fAecDefaultErl == TRUE ) && ( f_pVqeConfig->fAcousticEcho == TRUE ) ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->lAecDefaultErlDb != pChanEntry->VqeConfig.chAecDefaultErlDb ) + || ( f_pVqeConfig->fAcousticEcho != pChanEntry->VqeConfig.fAcousticEcho ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AecDefaultErlFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AecDefaultErlFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AecDefaultErlFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field. */ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( ( f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_NO_ECHO ) + && ( f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) ) + { + /* Convert the DB value to octasic's float format. (In energy) */ + usTempData = Oct6100ApiDbAmpHalfToOctFloat( 2 * f_pVqeConfig->lAecDefaultErlDb ); + } + else + { + /* Clear the AEC defautl ERL when using the no echo cancellation operation mode. */ + usTempData = 0x0; + } + + if ( ulFeatureFieldLength < 16 ) + usTempData = (UINT16)( usTempData >> ( 16 - ulFeatureFieldLength ) ); + + ulTempData |= ( usTempData << ulFeatureBitOffset ); + + /* Then save the DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the DTMF tone removal bit.*/ + if ( pSharedInfo->ImageInfo.fToneRemoval == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fDtmfToneRemoval != pChanEntry->VqeConfig.fDtmfToneRemoval ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.ToneRemovalFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.ToneRemovalFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.ToneRemovalFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + ulTempData |= ( ( (UINT32)f_pVqeConfig->fDtmfToneRemoval ) << ulFeatureBitOffset ); + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + + + /* Set the non-linear behavior A.*/ + if ( pSharedInfo->ImageInfo.fNonLinearityBehaviorA == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->ulNonLinearityBehaviorA != pChanEntry->VqeConfig.byNonLinearityBehaviorA ) + || ( f_pChannelOpen->ulEchoOperationMode != pChanEntry->byEchoOperationMode ) ) ) ) + { + UINT16 ausLookupTable[ 14 ] = { 0x3663, 0x3906, 0x399C, 0x3A47, 0x3B06, 0x3B99, 0x3C47, 0x3D02, 0x3D99, 0x3E47, 0x3F00, 0x3F99, 0x4042, 0x4100 }; + + ulFeatureBytesOffset = pSharedInfo->MemoryMap.PcmLeakFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.PcmLeakFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.PcmLeakFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /*If we support ANR level the TLV is shared over 2 bits*/ + if (ulFeatureBitOffset == 18) + { + ulFeatureBitOffset -= 2; + ausLookupTable[ f_pVqeConfig->ulNonLinearityBehaviorA ] &= 0xFFFC; + } + + if ( ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_NO_ECHO ) + || ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) ) + ulTempData |= ( 0x0 << ulFeatureBitOffset ); + else + ulTempData |= ( ausLookupTable[ f_pVqeConfig->ulNonLinearityBehaviorA ] << ulFeatureBitOffset ); + + /* Then save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Synch all the buffer playout field.*/ + if ( pSharedInfo->ImageInfo.fBufferPlayout == TRUE && f_fClearPlayoutPointers == TRUE ) + { + Oct6100BufferPlayoutStopDef( &BufferPlayoutStop ); + + BufferPlayoutStop.ulChannelHndl = cOCT6100_INVALID_HANDLE; + BufferPlayoutStop.fStopCleanly = TRUE; + + BufferPlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + ulResult = Oct6100ApiInvalidateChanPlayoutStructs( + f_pApiInstance, + &BufferPlayoutStop, + f_usChanIndex, + f_usEchoMemIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + BufferPlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_SOUT; + ulResult = Oct6100ApiInvalidateChanPlayoutStructs( + f_pApiInstance, + &BufferPlayoutStop, + f_usChanIndex, + f_usEchoMemIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*==============================================================================*/ + /* Write the 2100 Hz Echo Disabling mode */ + + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pChannelOpen->fEnableToneDisabler != pChanEntry->fEnableToneDisabler ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.ToneDisablerControlOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.ToneDisablerControlOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.ToneDisablerControlOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* This is a disable bit, so it must be set only if the enable flag is set to false. */ + if ( f_pChannelOpen->fEnableToneDisabler == FALSE ) + ulTempData |= 0x1 << ulFeatureBitOffset; + + /* Save the DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Write the Nlp Trivial enable flag. */ + + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( + + ( f_pChannelOpen->ulEchoOperationMode != pChanEntry->byEchoOperationMode ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.NlpTrivialFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.NlpTrivialFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.NlpTrivialFieldOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + if ( ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_NO_ECHO ) + || ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) ) + { + ulTempData |= TRUE << ulFeatureBitOffset; + } + + + /* Then write the DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Set the double talk behavior mode. */ + if ( pSharedInfo->ImageInfo.fDoubleTalkBehaviorFieldOfst == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->ulDoubleTalkBehavior != pChanEntry->VqeConfig.byDoubleTalkBehavior ) ) ) + { + /* The field is located in the CPURO structure. */ + ulFeatureBytesOffset = pSharedInfo->MemoryMap.DoubleTalkBehaviorFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.DoubleTalkBehaviorFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.DoubleTalkBehaviorFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + ulTempData |= (f_pVqeConfig->ulDoubleTalkBehavior << ulFeatureBitOffset ); + + /* Then save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Set the music protection enable. */ + if ( ( pSharedInfo->ImageInfo.fMusicProtection == TRUE ) + && ( pSharedInfo->ImageInfo.fMusicProtectionConfiguration == TRUE ) ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fEnableMusicProtection != pChanEntry->VqeConfig.fEnableMusicProtection ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.MusicProtectionFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.MusicProtectionFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.MusicProtectionFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + if ( f_pVqeConfig->fEnableMusicProtection == TRUE ) + ulTempData |= ( 1 << ulFeatureBitOffset ); + + /* Then save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteVqeAfMemory + +Description: This function configures the AF related VQE features of an + echo channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pVqeConfig Pointer to a VQE config structure. +f_pChannelOpen Pointer to a channel configuration structure. +f_usChanIndex Index of the echo channel in the API instance. +f_usEchoMemIndex Index of the echo channel within the SSPX memory. +f_fClearPlayoutPointers Flag indicating if the playout pointer should be cleared. +f_fModifyOnly Flag indicating if the configuration should be + modified only. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteVqeAfMemory +UINT32 Oct6100ApiWriteVqeAfMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fClearPlayoutPointers, + IN BOOL f_fModifyOnly ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + UINT32 ulTempData; + UINT32 ulAfConfigBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulMask; + UINT16 usTempData; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ); + + /*==============================================================================*/ + /* Write the AF CPU configuration of the channel feature by feature.*/ + + /* Calculate AF CPU configuration base address. */ + ulAfConfigBaseAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoMemIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst; + + /* Set initial value to zero.*/ + ulTempData = 0; + + /*==============================================================================*/ + /* Program the Maximum echo point within the Main channel memory.*/ + if ( pSharedInfo->ImageInfo.fMaxEchoPoint == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->lDefaultErlDb != pChanEntry->VqeConfig.chDefaultErlDb ) + || ( f_pChannelOpen->ulEchoOperationMode != pChanEntry->byEchoOperationMode ) ) ) ) + { + /* Write the echo tail length */ + ulFeatureBytesOffset = pSharedInfo->MemoryMap.ChanMainIoMaxEchoPointOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.ChanMainIoMaxEchoPointOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.ChanMainIoMaxEchoPointOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Convert the DB value to octasic's float format.*/ + if ( f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_NO_ECHO ) + { + usTempData = Oct6100ApiDbAmpHalfToOctFloat( 2 * f_pVqeConfig->lDefaultErlDb ); + } + else + { + /* Clear max echo point. No echo cancellation here. */ + usTempData = 0x0; + } + + if ( ulFeatureFieldLength < 16 ) + usTempData = (UINT16)( usTempData >> ( 16 - ulFeatureFieldLength ) ); + + ulTempData |= usTempData << ulFeatureBitOffset; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Set the non-linear behavior B.*/ + if ( pSharedInfo->ImageInfo.fNonLinearityBehaviorB == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->ulNonLinearityBehaviorB != pChanEntry->VqeConfig.byNonLinearityBehaviorB ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.NlpConvCapFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.NlpConvCapFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.NlpConvCapFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + ulTempData |= (f_pVqeConfig->ulNonLinearityBehaviorB << ulFeatureBitOffset ); + + /* Then save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Set the listener enhancement feature. */ + if ( pSharedInfo->ImageInfo.fListenerEnhancement == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb != pChanEntry->VqeConfig.bySoutAutomaticListenerEnhancementGainDb ) + || ( f_pVqeConfig->fSoutNaturalListenerEnhancement != pChanEntry->VqeConfig.fSoutNaturalListenerEnhancement ) + || ( f_pVqeConfig->ulSoutNaturalListenerEnhancementGainDb != pChanEntry->VqeConfig.bySoutNaturalListenerEnhancementGainDb ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AdaptiveAleOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AdaptiveAleOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AdaptiveAleOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb != 0 ) + { + UINT32 ulGainDb; + + ulGainDb = f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb / 3; + + /* Round up. */ + if ( ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb % 3 ) != 0x0 ) + ulGainDb ++; + + ulTempData |= ( ulGainDb << ulFeatureBitOffset ); + } + else if ( f_pVqeConfig->fSoutNaturalListenerEnhancement != 0 ) + { + UINT32 ulGainDb; + + ulGainDb = f_pVqeConfig->ulSoutNaturalListenerEnhancementGainDb / 3; + + /* Round up. */ + if ( ( f_pVqeConfig->ulSoutNaturalListenerEnhancementGainDb % 3 ) != 0x0 ) + ulGainDb ++; + + ulTempData |= ( ( 0x80 | ulGainDb ) << ulFeatureBitOffset ); + } + + /* Now write the DWORD where the field is located containing the new configuration. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Set the idle code detection enable. */ + if ( ( pSharedInfo->ImageInfo.fIdleCodeDetection == TRUE ) + && ( pSharedInfo->ImageInfo.fIdleCodeDetectionConfiguration == TRUE ) ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fIdleCodeDetection != pChanEntry->VqeConfig.fIdleCodeDetection ) ) ) + { + /* Calculate base address in the AF software configuration. */ + ulFeatureBytesOffset = pSharedInfo->MemoryMap.IdleCodeDetectionFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.IdleCodeDetectionFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.IdleCodeDetectionFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + if ( f_pVqeConfig->fIdleCodeDetection == FALSE ) + ulTempData |= ( 1 << ulFeatureBitOffset ); + + /* Then save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Set the AFT control field. */ + if ( pSharedInfo->ImageInfo.fAftControl == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pChannelOpen->ulEchoOperationMode != pChanEntry->byEchoOperationMode ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AftControlOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AftControlOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AftControlOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* If the operation mode is no echo, set the field such that echo cancellation is disabled. */ + if ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_NO_ECHO ) + { + ulTempData |= ( 0x1234 << ulFeatureBitOffset ); + } + else if ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) + { + /* For clarity. */ + ulTempData |= ( 0x0 << ulFeatureBitOffset ); + } + + /* Then save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteEchoMemory + +Description: This function configure an echo memory entry in internal memory.and + external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pTdmConfig Pointer to a TDM config structure. +f_pChannelOpen Pointer to a channel configuration structure. +f_usEchoIndex Echo channel index within the SSPX memory. +f_usRinRoutTsiIndex RIN/ROUT TSI index within the TSI chariot memory +f_usSinSoutTsiIndex SIN/SOUT TSI index within the TSI chariot memory + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteEchoMemory +UINT32 Oct6100ApiWriteEchoMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_TDM f_pTdmConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usEchoIndex, + IN UINT16 f_usRinRoutTsiIndex, + IN UINT16 f_usSinSoutTsiIndex ) + +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + UINT32 ulTempData; + UINT32 ulBaseAddress; + UINT32 ulRinPcmLaw; + UINT32 ulRoutPcmLaw; + UINT32 ulSinPcmLaw; + UINT32 ulSoutPcmLaw; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Set immediately the PCM law to be programmed in the SSPX and NLP memory.*/ + if ( f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + ulRinPcmLaw = f_pChannelOpen->TdmConfig.ulRoutPcmLaw; + ulRoutPcmLaw = f_pChannelOpen->TdmConfig.ulRoutPcmLaw; + ulSinPcmLaw = f_pChannelOpen->TdmConfig.ulSinPcmLaw; + ulSoutPcmLaw = f_pChannelOpen->TdmConfig.ulSinPcmLaw; + } + else /* f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN */ + { + ulRinPcmLaw = f_pChannelOpen->TdmConfig.ulRinPcmLaw; + ulRoutPcmLaw = f_pChannelOpen->TdmConfig.ulRinPcmLaw; + ulSinPcmLaw = f_pChannelOpen->TdmConfig.ulSoutPcmLaw; + ulSoutPcmLaw = f_pChannelOpen->TdmConfig.ulSoutPcmLaw; + } + + /*==============================================================================*/ + /* Configure the Global Static Configuration of the channel.*/ + + ulBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_usEchoIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + cOCT6100_CHANNEL_ROOT_GLOBAL_CONF_OFFSET; + + /* Set the PGSP context base address. */ + ulTempData = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + cOCT6100_CH_MAIN_PGSP_CONTEXT_OFFSET; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_PGSP_CONTEXT_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the PGSP init context base address. */ + ulTempData = ( cOCT6100_IMAGE_FILE_BASE + 0x200 ) & 0x07FFFFFF; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_PGSP_INIT_CONTEXT_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the RIN circular buffer base address. */ + ulTempData = ( pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainRinCBMemOfst) & 0x07FFFF00; + ulTempData |= ( ulRoutPcmLaw << cOCT6100_GSC_BUFFER_LAW_OFFSET ); + + /* Set the circular buffer size.*/ + if (( pSharedInfo->MemoryMap.ulChanMainRinCBMemSize & 0xFFFF00FF ) != 0 ) + return cOCT6100_ERR_CHANNEL_INVALID_RIN_CB_SIZE; + ulTempData |= pSharedInfo->MemoryMap.ulChanMainRinCBMemSize >> 8; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_RIN_CIRC_BUFFER_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the SIN circular buffer base address. */ + ulTempData = ( pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainSinCBMemOfst) & 0x07FFFF00; + ulTempData |= ( ulSinPcmLaw << cOCT6100_GSC_BUFFER_LAW_OFFSET ); + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_SIN_CIRC_BUFFER_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the SOUT circular buffer base address. */ + ulTempData = ( pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainSoutCBMemOfst ) & 0x07FFFF00; + ulTempData |= ( ulSoutPcmLaw << cOCT6100_GSC_BUFFER_LAW_OFFSET ); + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_SOUT_CIRC_BUFFER_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* ECHO SSPX Memory configuration.*/ + + WriteParams.ulWriteAddress = cOCT6100_ECHO_CONTROL_MEM_BASE + ( f_usEchoIndex * cOCT6100_ECHO_CONTROL_MEM_ENTRY_SIZE ); + + /* ECHO memory BASE + 2 */ + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = 0x0000; + + /* Set the echo control field.*/ + if ( ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_NO_ECHO ) + || ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) ) + { + WriteParams.usWriteData |= cOCT6100_ECHO_OP_MODE_NORMAL << cOCT6100_ECHO_CONTROL_MEM_AF_CONTROL; + } + else if ( f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_EXTERNAL ) + { + WriteParams.usWriteData |= f_pChannelOpen->ulEchoOperationMode << cOCT6100_ECHO_CONTROL_MEM_AF_CONTROL; + } + + /* Set the SIN/SOUT law.*/ + WriteParams.usWriteData |= ulSinPcmLaw << cOCT6100_ECHO_CONTROL_MEM_INPUT_LAW_OFFSET; + WriteParams.usWriteData |= ulSoutPcmLaw << cOCT6100_ECHO_CONTROL_MEM_OUTPUT_LAW_OFFSET; + + /* Set the TSI chariot memory field.*/ + WriteParams.usWriteData |= f_usSinSoutTsiIndex & cOCT6100_ECHO_CONTROL_MEM_TSI_MEM_MASK; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* ECHO memory BASE */ + WriteParams.ulWriteAddress -= 2; + WriteParams.usWriteData = cOCT6100_ECHO_CONTROL_MEM_ACTIVATE_ENTRY; + + /* Set the RIN/ROUT law.*/ + WriteParams.usWriteData |= ulRinPcmLaw << cOCT6100_ECHO_CONTROL_MEM_INPUT_LAW_OFFSET; + WriteParams.usWriteData |= ulRoutPcmLaw << cOCT6100_ECHO_CONTROL_MEM_OUTPUT_LAW_OFFSET; + + /* Set the RIN external echo control bit.*/ + if ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_EXTERNAL ) + WriteParams.usWriteData |= cOCT6100_ECHO_CONTROL_MEM_EXTERNAL_AF_CTRL; + + /* Set the TSI chariot memory field.*/ + WriteParams.usWriteData |= f_usRinRoutTsiIndex & cOCT6100_ECHO_CONTROL_MEM_TSI_MEM_MASK; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateOpenStruct + +Description: This function will copy the new parameter from the modify structure + into a channel open structure to be processed later by the same path + as the channel open function. + If a parameter is set to keep previous, it's current value will be + extracted from the channel entry in the API. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +IN f_pApiInstance Pointer to an API instance structure. +IN f_pChanModify Pointer to a channel modify structure. +IN OUT f_pChanOpen Pointer to a channel open structure. +IN f_pChanEntry Pointer to an API channel structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateOpenStruct +UINT32 Oct6100ApiUpdateOpenStruct( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChanModify, + IN OUT tPOCT6100_CHANNEL_OPEN f_pChanOpen, + IN tPOCT6100_API_CHANNEL f_pChanEntry ) +{ + + /* Check the generic Echo parameters.*/ + if ( f_pChanModify->ulEchoOperationMode == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->ulEchoOperationMode = f_pChanEntry->byEchoOperationMode; + else + f_pChanOpen->ulEchoOperationMode = f_pChanModify->ulEchoOperationMode; + + + if ( f_pChanModify->fEnableToneDisabler == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->fEnableToneDisabler = f_pChanEntry->fEnableToneDisabler; + else + f_pChanOpen->fEnableToneDisabler = f_pChanModify->fEnableToneDisabler; + + + if ( f_pChanModify->ulUserChanId == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->ulUserChanId = f_pChanEntry->ulUserChanId; + else + f_pChanOpen->ulUserChanId = f_pChanModify->ulUserChanId; + + + + /*======================================================================*/ + /* Now update the TDM config.*/ + /* Rin PCM LAW */ + if ( f_pChanModify->TdmConfig.ulRinPcmLaw == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRinPcmLaw = f_pChanEntry->TdmConfig.byRinPcmLaw; + else + f_pChanOpen->TdmConfig.ulRinPcmLaw = f_pChanModify->TdmConfig.ulRinPcmLaw; + + /* Sin PCM LAW */ + if ( f_pChanModify->TdmConfig.ulSinPcmLaw == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSinPcmLaw = f_pChanEntry->TdmConfig.bySinPcmLaw; + else + f_pChanOpen->TdmConfig.ulSinPcmLaw = f_pChanModify->TdmConfig.ulSinPcmLaw; + + /* Rout PCM LAW */ + if ( f_pChanModify->TdmConfig.ulRoutPcmLaw == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRoutPcmLaw = f_pChanEntry->TdmConfig.byRoutPcmLaw; + else + f_pChanOpen->TdmConfig.ulRoutPcmLaw = f_pChanModify->TdmConfig.ulRoutPcmLaw; + + /* Sout PCM LAW */ + if ( f_pChanModify->TdmConfig.ulSoutPcmLaw == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSoutPcmLaw = f_pChanEntry->TdmConfig.bySoutPcmLaw; + else + f_pChanOpen->TdmConfig.ulSoutPcmLaw = f_pChanModify->TdmConfig.ulSoutPcmLaw; + + + /* Rin Timeslot */ + if ( f_pChanModify->TdmConfig.ulRinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRinTimeslot = f_pChanEntry->TdmConfig.usRinTimeslot; + else + f_pChanOpen->TdmConfig.ulRinTimeslot = f_pChanModify->TdmConfig.ulRinTimeslot; + + /* Rin Stream */ + if ( f_pChanModify->TdmConfig.ulRinStream == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRinStream = f_pChanEntry->TdmConfig.usRinStream; + else + f_pChanOpen->TdmConfig.ulRinStream = f_pChanModify->TdmConfig.ulRinStream; + + /* Rin Num TSSTs */ + if ( f_pChanModify->TdmConfig.ulRinNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRinNumTssts = f_pChanEntry->TdmConfig.byRinNumTssts; + else + f_pChanOpen->TdmConfig.ulRinNumTssts = f_pChanModify->TdmConfig.ulRinNumTssts; + + + /* Sin Timeslot */ + if ( f_pChanModify->TdmConfig.ulSinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSinTimeslot = f_pChanEntry->TdmConfig.usSinTimeslot; + else + f_pChanOpen->TdmConfig.ulSinTimeslot = f_pChanModify->TdmConfig.ulSinTimeslot; + + /* Sin Stream */ + if ( f_pChanModify->TdmConfig.ulSinStream == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSinStream = f_pChanEntry->TdmConfig.usSinStream; + else + f_pChanOpen->TdmConfig.ulSinStream = f_pChanModify->TdmConfig.ulSinStream; + + /* Sin Num TSSTs */ + if ( f_pChanModify->TdmConfig.ulSinNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSinNumTssts = f_pChanEntry->TdmConfig.bySinNumTssts; + else + f_pChanOpen->TdmConfig.ulSinNumTssts = f_pChanModify->TdmConfig.ulSinNumTssts; + + + /* Rout Timeslot */ + if ( f_pChanModify->TdmConfig.ulRoutTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRoutTimeslot = f_pChanEntry->TdmConfig.usRoutTimeslot; + else + f_pChanOpen->TdmConfig.ulRoutTimeslot = f_pChanModify->TdmConfig.ulRoutTimeslot; + + /* Rout Stream */ + if ( f_pChanModify->TdmConfig.ulRoutStream == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRoutStream = f_pChanEntry->TdmConfig.usRoutStream; + else + f_pChanOpen->TdmConfig.ulRoutStream = f_pChanModify->TdmConfig.ulRoutStream; + + /* Rout Num TSSTs */ + if ( f_pChanModify->TdmConfig.ulRoutNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRoutNumTssts = f_pChanEntry->TdmConfig.byRoutNumTssts; + else + f_pChanOpen->TdmConfig.ulRoutNumTssts = f_pChanModify->TdmConfig.ulRoutNumTssts; + + + /* Sout Timeslot */ + if ( f_pChanModify->TdmConfig.ulSoutTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSoutTimeslot = f_pChanEntry->TdmConfig.usSoutTimeslot; + else + f_pChanOpen->TdmConfig.ulSoutTimeslot = f_pChanModify->TdmConfig.ulSoutTimeslot; + + /* Sout Stream */ + if ( f_pChanModify->TdmConfig.ulSoutStream == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSoutStream = f_pChanEntry->TdmConfig.usSoutStream; + else + f_pChanOpen->TdmConfig.ulSoutStream = f_pChanModify->TdmConfig.ulSoutStream; + + /* Sout Num TSSTs */ + if ( f_pChanModify->TdmConfig.ulSoutNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSoutNumTssts = f_pChanEntry->TdmConfig.bySoutNumTssts; + else + f_pChanOpen->TdmConfig.ulSoutNumTssts = f_pChanModify->TdmConfig.ulSoutNumTssts; + + /*======================================================================*/ + + /*======================================================================*/ + /* Now update the VQE config.*/ + + if ( f_pChanModify->VqeConfig.ulComfortNoiseMode == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulComfortNoiseMode = f_pChanEntry->VqeConfig.byComfortNoiseMode; + else + f_pChanOpen->VqeConfig.ulComfortNoiseMode = f_pChanModify->VqeConfig.ulComfortNoiseMode; + + if ( f_pChanModify->VqeConfig.fEnableNlp == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fEnableNlp = f_pChanEntry->VqeConfig.fEnableNlp; + else + f_pChanOpen->VqeConfig.fEnableNlp = f_pChanModify->VqeConfig.fEnableNlp; + + if ( f_pChanModify->VqeConfig.fEnableTailDisplacement == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fEnableTailDisplacement = f_pChanEntry->VqeConfig.fEnableTailDisplacement; + else + f_pChanOpen->VqeConfig.fEnableTailDisplacement = f_pChanModify->VqeConfig.fEnableTailDisplacement; + + if ( f_pChanModify->VqeConfig.ulTailDisplacement == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulTailDisplacement = f_pChanEntry->VqeConfig.usTailDisplacement; + else + f_pChanOpen->VqeConfig.ulTailDisplacement = f_pChanModify->VqeConfig.ulTailDisplacement; + + /* Tail length cannot be modifed. */ + f_pChanOpen->VqeConfig.ulTailLength = f_pChanEntry->VqeConfig.usTailLength; + + + + if ( f_pChanModify->VqeConfig.fRinDcOffsetRemoval == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fRinDcOffsetRemoval = f_pChanEntry->VqeConfig.fRinDcOffsetRemoval; + else + f_pChanOpen->VqeConfig.fRinDcOffsetRemoval = f_pChanModify->VqeConfig.fRinDcOffsetRemoval; + + + if ( f_pChanModify->VqeConfig.fRinLevelControl == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fRinLevelControl = f_pChanEntry->VqeConfig.fRinLevelControl; + else + f_pChanOpen->VqeConfig.fRinLevelControl = f_pChanModify->VqeConfig.fRinLevelControl; + + + if ( f_pChanModify->VqeConfig.fRinAutomaticLevelControl == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fRinAutomaticLevelControl = f_pChanEntry->VqeConfig.fRinAutomaticLevelControl; + else + f_pChanOpen->VqeConfig.fRinAutomaticLevelControl = f_pChanModify->VqeConfig.fRinAutomaticLevelControl; + + + if ( f_pChanModify->VqeConfig.fRinHighLevelCompensation == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fRinHighLevelCompensation = f_pChanEntry->VqeConfig.fRinHighLevelCompensation; + else + f_pChanOpen->VqeConfig.fRinHighLevelCompensation = f_pChanModify->VqeConfig.fRinHighLevelCompensation; + + + if ( f_pChanModify->VqeConfig.lRinHighLevelCompensationThresholdDb == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.lRinHighLevelCompensationThresholdDb = f_pChanEntry->VqeConfig.chRinHighLevelCompensationThresholdDb; + else + f_pChanOpen->VqeConfig.lRinHighLevelCompensationThresholdDb = f_pChanModify->VqeConfig.lRinHighLevelCompensationThresholdDb; + + + if ( f_pChanModify->VqeConfig.fSinDcOffsetRemoval == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fSinDcOffsetRemoval = f_pChanEntry->VqeConfig.fSinDcOffsetRemoval; + else + f_pChanOpen->VqeConfig.fSinDcOffsetRemoval = f_pChanModify->VqeConfig.fSinDcOffsetRemoval; + + + if ( f_pChanModify->VqeConfig.fSoutAdaptiveNoiseReduction == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fSoutAdaptiveNoiseReduction = f_pChanEntry->VqeConfig.fSoutAdaptiveNoiseReduction; + else + f_pChanOpen->VqeConfig.fSoutAdaptiveNoiseReduction = f_pChanModify->VqeConfig.fSoutAdaptiveNoiseReduction; + + + if ( f_pChanModify->VqeConfig.fSoutConferencingNoiseReduction == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fSoutConferencingNoiseReduction = f_pChanEntry->VqeConfig.fSoutConferencingNoiseReduction; + else + f_pChanOpen->VqeConfig.fSoutConferencingNoiseReduction = f_pChanModify->VqeConfig.fSoutConferencingNoiseReduction; + + + if ( f_pChanModify->VqeConfig.fSoutNoiseBleaching == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fSoutNoiseBleaching = f_pChanEntry->VqeConfig.fSoutNoiseBleaching; + else + f_pChanOpen->VqeConfig.fSoutNoiseBleaching = f_pChanModify->VqeConfig.fSoutNoiseBleaching; + + + if ( f_pChanModify->VqeConfig.fSoutLevelControl == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fSoutLevelControl = f_pChanEntry->VqeConfig.fSoutLevelControl; + else + f_pChanOpen->VqeConfig.fSoutLevelControl = f_pChanModify->VqeConfig.fSoutLevelControl; + + + if ( f_pChanModify->VqeConfig.fSoutAutomaticLevelControl == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fSoutAutomaticLevelControl = f_pChanEntry->VqeConfig.fSoutAutomaticLevelControl; + else + f_pChanOpen->VqeConfig.fSoutAutomaticLevelControl = f_pChanModify->VqeConfig.fSoutAutomaticLevelControl; + + + if ( f_pChanModify->VqeConfig.lRinLevelControlGainDb == ( (INT32)cOCT6100_KEEP_PREVIOUS_SETTING ) ) + f_pChanOpen->VqeConfig.lRinLevelControlGainDb = f_pChanEntry->VqeConfig.chRinLevelControlGainDb; + else + f_pChanOpen->VqeConfig.lRinLevelControlGainDb = f_pChanModify->VqeConfig.lRinLevelControlGainDb; + + + if ( f_pChanModify->VqeConfig.lSoutLevelControlGainDb == ( (INT32)cOCT6100_KEEP_PREVIOUS_SETTING ) ) + f_pChanOpen->VqeConfig.lSoutLevelControlGainDb = f_pChanEntry->VqeConfig.chSoutLevelControlGainDb; + else + f_pChanOpen->VqeConfig.lSoutLevelControlGainDb = f_pChanModify->VqeConfig.lSoutLevelControlGainDb; + + + if ( f_pChanModify->VqeConfig.lRinAutomaticLevelControlTargetDb == ( (INT32)cOCT6100_KEEP_PREVIOUS_SETTING ) ) + f_pChanOpen->VqeConfig.lRinAutomaticLevelControlTargetDb = f_pChanEntry->VqeConfig.chRinAutomaticLevelControlTargetDb; + else + f_pChanOpen->VqeConfig.lRinAutomaticLevelControlTargetDb = f_pChanModify->VqeConfig.lRinAutomaticLevelControlTargetDb; + + + if ( f_pChanModify->VqeConfig.lSoutAutomaticLevelControlTargetDb == ( (INT32)cOCT6100_KEEP_PREVIOUS_SETTING ) ) + f_pChanOpen->VqeConfig.lSoutAutomaticLevelControlTargetDb = f_pChanEntry->VqeConfig.chSoutAutomaticLevelControlTargetDb; + else + f_pChanOpen->VqeConfig.lSoutAutomaticLevelControlTargetDb = f_pChanModify->VqeConfig.lSoutAutomaticLevelControlTargetDb; + + + if ( f_pChanModify->VqeConfig.lDefaultErlDb == ( (INT32)cOCT6100_KEEP_PREVIOUS_SETTING ) ) + f_pChanOpen->VqeConfig.lDefaultErlDb = f_pChanEntry->VqeConfig.chDefaultErlDb; + else + f_pChanOpen->VqeConfig.lDefaultErlDb = f_pChanModify->VqeConfig.lDefaultErlDb; + + + if ( f_pChanModify->VqeConfig.lAecDefaultErlDb == ( (INT32)cOCT6100_KEEP_PREVIOUS_SETTING ) ) + f_pChanOpen->VqeConfig.lAecDefaultErlDb = f_pChanEntry->VqeConfig.chAecDefaultErlDb; + else + f_pChanOpen->VqeConfig.lAecDefaultErlDb = f_pChanModify->VqeConfig.lAecDefaultErlDb; + + + if ( f_pChanModify->VqeConfig.ulAecTailLength == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulAecTailLength = f_pChanEntry->VqeConfig.usAecTailLength; + else + f_pChanOpen->VqeConfig.ulAecTailLength = f_pChanModify->VqeConfig.ulAecTailLength; + + + if ( f_pChanModify->VqeConfig.fAcousticEcho == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fAcousticEcho = f_pChanEntry->VqeConfig.fAcousticEcho; + else + f_pChanOpen->VqeConfig.fAcousticEcho = f_pChanModify->VqeConfig.fAcousticEcho; + + + if ( f_pChanModify->VqeConfig.fDtmfToneRemoval == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fDtmfToneRemoval = f_pChanEntry->VqeConfig.fDtmfToneRemoval; + else + f_pChanOpen->VqeConfig.fDtmfToneRemoval = f_pChanModify->VqeConfig.fDtmfToneRemoval; + + + + + + if ( f_pChanModify->VqeConfig.ulNonLinearityBehaviorA == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulNonLinearityBehaviorA = f_pChanEntry->VqeConfig.byNonLinearityBehaviorA; + else + f_pChanOpen->VqeConfig.ulNonLinearityBehaviorA = f_pChanModify->VqeConfig.ulNonLinearityBehaviorA; + + + if ( f_pChanModify->VqeConfig.ulNonLinearityBehaviorB == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulNonLinearityBehaviorB = f_pChanEntry->VqeConfig.byNonLinearityBehaviorB; + else + f_pChanOpen->VqeConfig.ulNonLinearityBehaviorB = f_pChanModify->VqeConfig.ulNonLinearityBehaviorB; + + + if ( f_pChanModify->VqeConfig.ulDoubleTalkBehavior == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulDoubleTalkBehavior = f_pChanEntry->VqeConfig.byDoubleTalkBehavior; + else + f_pChanOpen->VqeConfig.ulDoubleTalkBehavior = f_pChanModify->VqeConfig.ulDoubleTalkBehavior; + + + if ( f_pChanModify->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb = f_pChanEntry->VqeConfig.bySoutAutomaticListenerEnhancementGainDb; + else + f_pChanOpen->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb = f_pChanModify->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb; + + + if ( f_pChanModify->VqeConfig.ulSoutNaturalListenerEnhancementGainDb == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulSoutNaturalListenerEnhancementGainDb = f_pChanEntry->VqeConfig.bySoutNaturalListenerEnhancementGainDb; + else + f_pChanOpen->VqeConfig.ulSoutNaturalListenerEnhancementGainDb = f_pChanModify->VqeConfig.ulSoutNaturalListenerEnhancementGainDb; + + + if ( f_pChanModify->VqeConfig.fSoutNaturalListenerEnhancement == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fSoutNaturalListenerEnhancement = f_pChanEntry->VqeConfig.fSoutNaturalListenerEnhancement; + else + f_pChanOpen->VqeConfig.fSoutNaturalListenerEnhancement = f_pChanModify->VqeConfig.fSoutNaturalListenerEnhancement; + + + if ( f_pChanModify->VqeConfig.fRoutNoiseReduction == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fRoutNoiseReduction = f_pChanEntry->VqeConfig.fRoutNoiseReduction; + else + f_pChanOpen->VqeConfig.fRoutNoiseReduction = f_pChanModify->VqeConfig.fRoutNoiseReduction; + + if ( f_pChanModify->VqeConfig.lRoutNoiseReductionLevelGainDb == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.lRoutNoiseReductionLevelGainDb = f_pChanEntry->VqeConfig.chRoutNoiseReductionLevelGainDb; + else + f_pChanOpen->VqeConfig.lRoutNoiseReductionLevelGainDb = f_pChanModify->VqeConfig.lRoutNoiseReductionLevelGainDb; + + + if ( f_pChanModify->VqeConfig.lAnrSnrEnhancementDb == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.lAnrSnrEnhancementDb = f_pChanEntry->VqeConfig.chAnrSnrEnhancementDb; + else + f_pChanOpen->VqeConfig.lAnrSnrEnhancementDb = f_pChanModify->VqeConfig.lAnrSnrEnhancementDb; + + + if ( f_pChanModify->VqeConfig.ulAnrVoiceNoiseSegregation == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulAnrVoiceNoiseSegregation = f_pChanEntry->VqeConfig.byAnrVoiceNoiseSegregation; + else + f_pChanOpen->VqeConfig.ulAnrVoiceNoiseSegregation = f_pChanModify->VqeConfig.ulAnrVoiceNoiseSegregation; + + + if ( f_pChanModify->VqeConfig.ulToneDisablerVqeActivationDelay == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulToneDisablerVqeActivationDelay = f_pChanEntry->VqeConfig.usToneDisablerVqeActivationDelay; + else + f_pChanOpen->VqeConfig.ulToneDisablerVqeActivationDelay = f_pChanModify->VqeConfig.ulToneDisablerVqeActivationDelay; + + + if ( f_pChanModify->VqeConfig.fEnableMusicProtection == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fEnableMusicProtection = f_pChanEntry->VqeConfig.fEnableMusicProtection; + else + f_pChanOpen->VqeConfig.fEnableMusicProtection = f_pChanModify->VqeConfig.fEnableMusicProtection; + + + if ( f_pChanModify->VqeConfig.fIdleCodeDetection == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fIdleCodeDetection = f_pChanEntry->VqeConfig.fIdleCodeDetection; + else + f_pChanOpen->VqeConfig.fIdleCodeDetection = f_pChanModify->VqeConfig.fIdleCodeDetection; + + /*======================================================================*/ + + + /*======================================================================*/ + /* Finaly the codec config.*/ + + if ( f_pChanModify->CodecConfig.ulDecoderPort == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->CodecConfig.ulDecoderPort = f_pChanEntry->CodecConfig.byDecoderPort; + else + f_pChanOpen->CodecConfig.ulDecoderPort = f_pChanModify->CodecConfig.ulDecoderPort; + + + if ( f_pChanModify->CodecConfig.ulDecodingRate == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->CodecConfig.ulDecodingRate = f_pChanEntry->CodecConfig.byDecodingRate; + else + f_pChanOpen->CodecConfig.ulDecodingRate = f_pChanModify->CodecConfig.ulDecodingRate; + + + if ( f_pChanModify->CodecConfig.ulEncoderPort == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->CodecConfig.ulEncoderPort = f_pChanEntry->CodecConfig.byEncoderPort; + else + f_pChanOpen->CodecConfig.ulEncoderPort = f_pChanModify->CodecConfig.ulEncoderPort; + + + if ( f_pChanModify->CodecConfig.ulEncodingRate == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->CodecConfig.ulEncodingRate = f_pChanEntry->CodecConfig.byEncodingRate; + else + f_pChanOpen->CodecConfig.ulEncodingRate = f_pChanModify->CodecConfig.ulEncodingRate; + + if ( f_pChanModify->CodecConfig.fEnableSilenceSuppression == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->CodecConfig.fEnableSilenceSuppression = f_pChanEntry->CodecConfig.fEnableSilenceSuppression; + else + f_pChanOpen->CodecConfig.fEnableSilenceSuppression = f_pChanModify->CodecConfig.fEnableSilenceSuppression; + + if ( f_pChanModify->CodecConfig.ulPhasingType == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->CodecConfig.ulPhasingType = f_pChanEntry->CodecConfig.byPhasingType; + else + f_pChanOpen->CodecConfig.ulPhasingType = f_pChanModify->CodecConfig.ulPhasingType; + + if ( f_pChanModify->CodecConfig.ulPhase == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->CodecConfig.ulPhase = f_pChanEntry->CodecConfig.byPhase; + else + f_pChanOpen->CodecConfig.ulPhase = f_pChanModify->CodecConfig.ulPhase; + + if ( f_pChanModify->CodecConfig.ulPhasingTsstHndl == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( f_pChanEntry->usPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + { + tPOCT6100_API_PHASING_TSST pPhasingEntry; + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPhasingEntry, f_pChanEntry->usPhasingTsstIndex ); + + /* Now recreate the Phasing TSST handle.*/ + f_pChanOpen->CodecConfig.ulPhasingTsstHndl = cOCT6100_HNDL_TAG_PHASING_TSST | (pPhasingEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_pChanEntry->usPhasingTsstIndex; + } + else + { + f_pChanOpen->CodecConfig.ulPhasingTsstHndl = cOCT6100_INVALID_HANDLE; + } + } + else + { + f_pChanOpen->CodecConfig.ulPhasingTsstHndl = f_pChanModify->CodecConfig.ulPhasingTsstHndl; + } + + f_pChanOpen->CodecConfig.ulAdpcmNibblePosition = f_pChanEntry->CodecConfig.byAdpcmNibblePosition; + /*======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRetrieveNlpConfDword + +Description: This function is used by the API to store on a per channel basis + the various confguration DWORD from the device. The API performs + less read to the chip that way since it is always in synch with the + chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChanEntry Pointer to an API channel structure.. +f_ulAddress Address that needs to be modified.. +f_pulConfigDword Pointer to the content stored in the API located at the + desired address. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRetrieveNlpConfDword +UINT32 Oct6100ApiRetrieveNlpConfDword( + + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_CHANNEL f_pChanEntry, + IN UINT32 f_ulAddress, + OUT PUINT32 f_pulConfigDword ) +{ + UINT32 ulResult; + UINT32 ulFirstEmptyIndex = 0xFFFFFFFF; + UINT32 i; + + /* Search for the Dword.*/ + for ( i = 0; i < cOCT6100_MAX_NLP_CONF_DWORD; i++ ) + { + if ( ( ulFirstEmptyIndex == 0xFFFFFFFF ) && ( f_pChanEntry->aulNlpConfDword[ i ][ 0 ] == 0x0 ) ) + ulFirstEmptyIndex = i; + + if ( f_pChanEntry->aulNlpConfDword[ i ][ 0 ] == f_ulAddress ) + { + /* We found the matching Dword.*/ + *f_pulConfigDword = f_pChanEntry->aulNlpConfDword[ i ][ 1 ]; + return cOCT6100_ERR_OK; + } + } + + if ( i == cOCT6100_MAX_NLP_CONF_DWORD && ulFirstEmptyIndex == 0xFFFFFFFF ) + return cOCT6100_ERR_FATAL_8E; + + /* We did not found any entry, let's create a new entry.*/ + f_pChanEntry->aulNlpConfDword[ ulFirstEmptyIndex ][ 0 ] = f_ulAddress; + + + /* Read the DWORD where the field is located.*/ + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulAddress, + f_pulConfigDword ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiSaveNlpConfDword + +Description: This function stores a configuration Dword within an API channel + structure and then writes it into the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChanEntry Pointer to an API channel structure.. +f_ulAddress Address that needs to be modified.. +f_pulConfigDword content to be stored in the API located at the + desired address. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiSaveNlpConfDword +UINT32 Oct6100ApiSaveNlpConfDword( + + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_CHANNEL f_pChanEntry, + IN UINT32 f_ulAddress, + IN UINT32 f_ulConfigDword ) +{ + UINT32 ulResult; + UINT32 i; + + /* Search for the Dword.*/ + for ( i = 0; i < cOCT6100_MAX_NLP_CONF_DWORD; i++ ) + { + + if ( f_pChanEntry->aulNlpConfDword[ i ][ 0 ] == f_ulAddress ) + { + /* We found the matching Dword.*/ + f_pChanEntry->aulNlpConfDword[ i ][ 1 ] = f_ulConfigDword; + break; + } + } + + if ( i == cOCT6100_MAX_NLP_CONF_DWORD ) + return cOCT6100_ERR_FATAL_8F; + + + /* Write the config DWORD.*/ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, + f_ulAddress, + f_ulConfigDword ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelCreateBiDirSer + +Description: Creates a bidirectional echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelCreateBiDir Pointer to a create bidirectionnal channel structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelCreateBiDirSer +UINT32 Oct6100ChannelCreateBiDirSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir ) +{ + UINT16 usFirstChanIndex; + UINT16 usFirstChanExtraTsiIndex; + UINT16 usFirstChanSinCopyEventIndex; + UINT16 usFirstChanSoutCopyEventIndex; + UINT16 usSecondChanIndex; + UINT16 usSecondChanExtraTsiIndex; + UINT16 usSecondChanSinCopyEventIndex; + UINT16 usSecondChanSoutCopyEventIndex; + UINT16 usBiDirChanIndex; + UINT32 ulResult; + + + /* Check the user's configuration of the bidir channel for errors. */ + ulResult = Oct6100ApiCheckChannelCreateBiDirParams( f_pApiInstance, + f_pChannelCreateBiDir, + &usFirstChanIndex, + &usFirstChanExtraTsiIndex, + &usFirstChanSinCopyEventIndex, + &usSecondChanIndex, + &usSecondChanExtraTsiIndex, + &usSecondChanSinCopyEventIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the bidir channel. */ + ulResult = Oct6100ApiReserveChannelCreateBiDirResources(f_pApiInstance, + + &usBiDirChanIndex, + &usFirstChanExtraTsiIndex, + &usFirstChanSinCopyEventIndex, + &usFirstChanSoutCopyEventIndex, + &usSecondChanExtraTsiIndex, + &usSecondChanSinCopyEventIndex, + &usSecondChanSoutCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write all necessary structures to activate the echo cancellation channel. */ + ulResult = Oct6100ApiWriteChannelCreateBiDirStructs( f_pApiInstance, + + usFirstChanIndex, + usFirstChanExtraTsiIndex, + usFirstChanSinCopyEventIndex, + usFirstChanSoutCopyEventIndex, + usSecondChanIndex, + usSecondChanExtraTsiIndex, + usSecondChanSinCopyEventIndex, + usSecondChanSoutCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the new echo cancellation channels's entry in the ECHO channel list. */ + ulResult = Oct6100ApiUpdateBiDirChannelEntry( f_pApiInstance, + f_pChannelCreateBiDir, + usBiDirChanIndex, + usFirstChanIndex, + usFirstChanExtraTsiIndex, + usFirstChanSinCopyEventIndex, + usFirstChanSoutCopyEventIndex, + usSecondChanIndex, + usSecondChanExtraTsiIndex, + usSecondChanSinCopyEventIndex, + usSecondChanSoutCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckChannelCreateBiDirParams + +Description: Checks the user's parameter passed to the create bidirectional channel + function. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelCreateBiDir Pointer to a create bidirectionnal channel structure. +f_pusFirstChanIndex Pointer to the first channel index. +f_pusFirstChanExtraTsiIndex Pointer to the first channel extra TSI index. +f_pusFirstChanSinCopyEventIndex Pointer to the first channel Sin copy event index. +f_pusSecondChanIndex Pointer to the second channel index. +f_pusSecondChanExtraTsiIndex Pointer to the second channel extra TSI index. +f_pusSecondChanSinCopyEventIndex Pointer to the second channel Sin copy event index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckChannelCreateBiDirParams +UINT32 Oct6100ApiCheckChannelCreateBiDirParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir, + OUT PUINT16 f_pusFirstChanIndex, + OUT PUINT16 f_pusFirstChanExtraTsiIndex, + OUT PUINT16 f_pusFirstChanSinCopyEventIndex, + OUT PUINT16 f_pusSecondChanIndex, + OUT PUINT16 f_pusSecondChanExtraTsiIndex, + OUT PUINT16 f_pusSecondChanSinCopyEventIndex + + ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pFirstChanEntry; + tPOCT6100_API_CHANNEL pSecondChanEntry; + UINT32 ulEntryOpenCnt; + BOOL fCheckTssts = TRUE; + + /* Obtain shared resources pointer.*/ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* validate the bidirectional channel handle memory.*/ + if ( f_pChannelCreateBiDir->pulBiDirChannelHndl == NULL ) + return cOCT6100_ERR_CHANNEL_BIDIR_CHANNEL_HANDLE; + + + + /* Check if bi-dir channels are activated. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxBiDirChannels == 0 ) + return cOCT6100_ERR_CHANNEL_BIDIR_DISABLED; + + /*=======================================================================*/ + /* Verify the first channel handle. */ + + if ( (f_pChannelCreateBiDir->ulFirstChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_BIDIR_FIRST_CHANNEL_HANDLE; + + *f_pusFirstChanIndex = (UINT16)( f_pChannelCreateBiDir->ulFirstChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusFirstChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_BIDIR_FIRST_CHANNEL_HANDLE; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pFirstChanEntry, *f_pusFirstChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelCreateBiDir->ulFirstChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pFirstChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pFirstChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_BIDIR_FIRST_CHANNEL_HANDLE; + + /* Check the specific state of the channel.*/ + if ( pFirstChanEntry->fRinRoutCodecActive == TRUE && pFirstChanEntry->CodecConfig.byEncoderPort != cOCT6100_CHANNEL_PORT_ROUT) + return cOCT6100_ERR_CHANNEL_CODEC_ACTIVATED; + if ( pFirstChanEntry->fSinSoutCodecActive == TRUE && pFirstChanEntry->CodecConfig.byEncoderPort != cOCT6100_CHANNEL_PORT_SOUT) + return cOCT6100_ERR_CHANNEL_CODEC_ACTIVATED; + if ( pFirstChanEntry->fBiDirChannel == TRUE ) + return cOCT6100_ERR_CHANNEL_ALREADY_BIDIR; + + if ( pFirstChanEntry->usBridgeIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_FIRST_CHAN_IN_CONFERENCE; + + if ( fCheckTssts == TRUE ) + { + if ( pFirstChanEntry->usSoutTsstIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_FIRST_CHAN_SOUT_PORT; + if ( pFirstChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_FIRST_CHAN_RIN_PORT; + } + + /* Return the desired info.*/ + *f_pusFirstChanExtraTsiIndex = pFirstChanEntry->usExtraSinTsiMemIndex; + *f_pusFirstChanSinCopyEventIndex = pFirstChanEntry->usSinCopyEventIndex; + /*=======================================================================*/ + + /*=======================================================================*/ + /* Verify the second channel handle. */ + + if ( (f_pChannelCreateBiDir->ulSecondChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_BIDIR_SECOND_CHANNEL_HANDLE; + + *f_pusSecondChanIndex = (UINT16)( f_pChannelCreateBiDir->ulSecondChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusSecondChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_BIDIR_SECOND_CHANNEL_HANDLE; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pSecondChanEntry, *f_pusSecondChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelCreateBiDir->ulSecondChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pSecondChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pSecondChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_BIDIR_SECOND_CHANNEL_HANDLE; + + /* Check the specific state of the channel.*/ + if ( pSecondChanEntry->fRinRoutCodecActive == TRUE && pSecondChanEntry->CodecConfig.byEncoderPort != cOCT6100_CHANNEL_PORT_ROUT) + return cOCT6100_ERR_CHANNEL_CODEC_ACTIVATED; + if ( pSecondChanEntry->fSinSoutCodecActive == TRUE && pSecondChanEntry->CodecConfig.byEncoderPort != cOCT6100_CHANNEL_PORT_SOUT) + { + + return cOCT6100_ERR_CHANNEL_CODEC_ACTIVATED; + } + + if ( pSecondChanEntry->fBiDirChannel == TRUE ) + return cOCT6100_ERR_CHANNEL_ALREADY_BIDIR; + + if ( fCheckTssts == TRUE ) + { + if ( pSecondChanEntry->usSoutTsstIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_SECOND_CHAN_SOUT_PORT; + if ( pSecondChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_SECOND_CHAN_RIN_PORT; + } + + if ( pSecondChanEntry->usBridgeIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_SECOND_CHAN_IN_CONFERENCE; + + /* Return the desired info.*/ + *f_pusSecondChanExtraTsiIndex = pSecondChanEntry->usExtraSinTsiMemIndex; + *f_pusSecondChanSinCopyEventIndex = pSecondChanEntry->usSinCopyEventIndex; + /*=======================================================================*/ + + /* Check the law compatibility.*/ + if ( pFirstChanEntry->TdmConfig.bySoutPcmLaw != pSecondChanEntry->TdmConfig.byRinPcmLaw || + pFirstChanEntry->TdmConfig.byRinPcmLaw != pSecondChanEntry->TdmConfig.bySoutPcmLaw ) + return cOCT6100_ERR_CHANNEL_BIDIR_PCM_LAW; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveChannelCreateBiDirResources + +Description: Reserves all resources needed for the new bidirectional channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pusBiDirChanIndex Pointer to the index of the bidirectionnal channel within the API instance. +f_pusFirstChanExtraTsiIndex Pointer to the first channel extra TSI index. +f_pusFirstChanSinCopyEventIndex Pointer to the first channel Sin copy event index. +f_pusFirstChanSoutCopyEventIndex Pointer to the first channel Sout copy event index. +f_pusSecondChanExtraTsiIndex Pointer to the second channel extra TSI index. +f_pusSecondChanSinCopyEventIndex Pointer to the second channel Sin copy event index. +f_pusSecondChanSoutCopyEventIndex Pointer to the second channel Sout copy event index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveChannelCreateBiDirResources +UINT32 Oct6100ApiReserveChannelCreateBiDirResources( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + + OUT PUINT16 f_pusBiDirChanIndex, + IN OUT PUINT16 f_pusFirstChanExtraTsiIndex, + IN OUT PUINT16 f_pusFirstChanSinCopyEventIndex, + OUT PUINT16 f_pusFirstChanSoutCopyEventIndex, + IN OUT PUINT16 f_pusSecondChanExtraTsiIndex, + IN OUT PUINT16 f_pusSecondChanSinCopyEventIndex, + OUT PUINT16 f_pusSecondChanSoutCopyEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult = cOCT6100_ERR_OK; + UINT32 ulTempVar; + + BOOL fBiDirChanIndex = FALSE; + BOOL fFirstExtraTsi = FALSE; + BOOL fSecondExtraTsi = FALSE; + BOOL fFirstSinCopyEvent = FALSE; + BOOL fSecondSinCopyEvent = FALSE; + BOOL fFirstSoutCopyEvent = FALSE; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /*===============================================================================*/ + /* Verify and reserve the resources that might already by allocated. */ + + + { + if ( *f_pusFirstChanExtraTsiIndex == cOCT6100_INVALID_INDEX ) + { + /* Reserve the first Extra TSI memory entry */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, + f_pusFirstChanExtraTsiIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + fFirstExtraTsi = TRUE; + } + + if ( *f_pusFirstChanSinCopyEventIndex == cOCT6100_INVALID_INDEX && ulResult == cOCT6100_ERR_OK ) + { + /* Reserve the Sin copy event for the first channel.*/ + ulResult = Oct6100ApiReserveMixerEventEntry ( f_pApiInstance, + f_pusFirstChanSinCopyEventIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + fFirstSinCopyEvent = TRUE; + } + } + + if ( *f_pusSecondChanExtraTsiIndex == cOCT6100_INVALID_INDEX && ulResult == cOCT6100_ERR_OK ) + { + /* Reserve the second Extra TSI memory entry */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, + f_pusSecondChanExtraTsiIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + fSecondExtraTsi = TRUE; + } + + if ( *f_pusSecondChanSinCopyEventIndex == cOCT6100_INVALID_INDEX && ulResult == cOCT6100_ERR_OK ) + { + /* Reserve the Sin copy event for the second channel.*/ + ulResult = Oct6100ApiReserveMixerEventEntry ( f_pApiInstance, + f_pusSecondChanSinCopyEventIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + fSecondSinCopyEvent = TRUE; + } + /*===============================================================================*/ + + + /*===============================================================================*/ + /* Now reserve all the resources specific to bidirectional channels */ + + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReserveBiDirChanEntry( f_pApiInstance, + f_pusBiDirChanIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fBiDirChanIndex = TRUE; + + + { + + /* Reserve the first channel Sout copy mixer event.*/ + ulResult = Oct6100ApiReserveMixerEventEntry ( f_pApiInstance, + f_pusFirstChanSoutCopyEventIndex ); + } + + if ( ulResult == cOCT6100_ERR_OK ) + { + fFirstSoutCopyEvent = TRUE; + + /* Reserve the second channel Sout copy mixer event.*/ + ulResult = Oct6100ApiReserveMixerEventEntry ( f_pApiInstance, + f_pusSecondChanSoutCopyEventIndex ); + } + } + } + + /*===============================================================================*/ + + + /*===============================================================================*/ + /* Release the resources if something went wrong */ + if ( ulResult != cOCT6100_ERR_OK ) + { + /*===============================================================================*/ + /* Release the previously reserved echo resources .*/ + if ( fBiDirChanIndex == TRUE ) + { + ulTempVar = Oct6100ApiReleaseBiDirChanEntry( f_pApiInstance, + *f_pusBiDirChanIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fFirstExtraTsi == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, + *f_pusFirstChanExtraTsiIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fSecondExtraTsi == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, + *f_pusSecondChanExtraTsiIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fFirstSinCopyEvent == TRUE ) + { + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, + *f_pusFirstChanSinCopyEventIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fSecondSinCopyEvent == TRUE ) + { + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, + *f_pusSecondChanSinCopyEventIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( ( fFirstSoutCopyEvent == TRUE ) + + ) + { + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, + *f_pusFirstChanSoutCopyEventIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /*===============================================================================*/ + + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteChannelCreateBiDirStructs + +Description: Performs all the required structure writes to configure the + new echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usFirstChanIndex Pointer to the first channel index. +f_usFirstChanExtraTsiIndex Pointer to the first channel extra TSI index. +f_usFirstChanSinCopyEventIndex Pointer to the first channel Sin copy event index. +f_usFirstChanSoutCopyEventIndex Pointer to the first channel Sout copy event index. +f_usFirstChanIndex Pointer to the second channel index. +f_usSecondChanExtraTsiIndex Pointer to the second channel extra TSI index. +f_usSecondChanSinCopyEventIndex Pointer to the second channel Sin copy event index. +f_usSecondChanSoutCopyEventIndex Pointer to the second channel Sout copy event index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteChannelCreateBiDirStructs +UINT32 Oct6100ApiWriteChannelCreateBiDirStructs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + + IN UINT16 f_usFirstChanIndex, + IN UINT16 f_usFirstChanExtraTsiIndex, + IN UINT16 f_usFirstChanSinCopyEventIndex, + IN UINT16 f_usFirstChanSoutCopyEventIndex, + IN UINT16 f_usSecondChanIndex, + IN UINT16 f_usSecondChanExtraTsiIndex, + IN UINT16 f_usSecondChanSinCopyEventIndex, + IN UINT16 f_usSecondChanSoutCopyEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pFirstChanEntry; + tPOCT6100_API_CHANNEL pSecondChanEntry; + + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*==============================================================================*/ + /* Get a pointer to the two channel entry.*/ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pFirstChanEntry, f_usFirstChanIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pSecondChanEntry, f_usSecondChanIndex ); + + + + + { + /*==============================================================================*/ + /* Configure the Tsst control memory and add the Sin copy event if necessary. */ + + /*=======================================================================*/ + /* Program the Sin Copy event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usFirstChanSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= f_usFirstChanExtraTsiIndex; + WriteParams.usWriteData |= pFirstChanEntry->TdmConfig.bySinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( pFirstChanEntry->usSinSoutTsiMemIndex ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Configure the TSST memory.*/ + if ( pFirstChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pFirstChanEntry->usSinTsstIndex, + f_usFirstChanExtraTsiIndex, + pFirstChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Now insert the event into the event list.*/ + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_usFirstChanSinCopyEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY, + f_usFirstChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + } + + + + /*==============================================================================*/ + /* Configure the Tsst control memory and add the Sin copy event if necessary.*/ + + /*=======================================================================*/ + /* Program the Sin Copy event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usSecondChanSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= f_usSecondChanExtraTsiIndex; + WriteParams.usWriteData |= pSecondChanEntry->TdmConfig.bySinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( pSecondChanEntry->usSinSoutTsiMemIndex ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Configure the TSST memory.*/ + if ( pSecondChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pSecondChanEntry->usSinTsstIndex, + f_usSecondChanExtraTsiIndex, + pSecondChanEntry->TdmConfig.bySinPcmLaw ); + } + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Now insert the event into the event list.*/ + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_usSecondChanSinCopyEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY, + f_usSecondChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + + /*==============================================================================*/ + /* Now, let's configure the two Sout copy events.*/ + + + /* First event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usFirstChanSoutCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= pFirstChanEntry->usSinSoutTsiMemIndex; + WriteParams.usWriteData |= pFirstChanEntry->TdmConfig.bySoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pSecondChanEntry->usRinRoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_usFirstChanSoutCopyEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY, + f_usFirstChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + /* Second event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usSecondChanSoutCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= pSecondChanEntry->usSinSoutTsiMemIndex; + WriteParams.usWriteData |= pSecondChanEntry->TdmConfig.bySoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pFirstChanEntry->usRinRoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_usSecondChanSoutCopyEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY, + f_usSecondChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Clear + release the silence events if they were created. */ + + if ( pFirstChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pFirstChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pFirstChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_E0; + + pFirstChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + + if ( ( pSecondChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + + ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pSecondChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pSecondChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_E0; + + pSecondChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateBiDirChannelEntry + +Description: Updates the new bidir channel and the channel used to create that channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateBiDirChannelEntry +UINT32 Oct6100ApiUpdateBiDirChannelEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir, + IN UINT16 f_usBiDirChanIndex, + IN UINT16 f_usFirstChanIndex, + IN UINT16 f_usFirstChanExtraTsiIndex, + IN UINT16 f_usFirstChanSinCopyEventIndex, + IN UINT16 f_usFirstChanSoutCopyEventIndex, + IN UINT16 f_usSecondChanIndex, + IN UINT16 f_usSecondChanExtraTsiIndex, + IN UINT16 f_usSecondChanSinCopyEventIndex, + IN UINT16 f_usSecondChanSoutCopyEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pFirstChanEntry; + tPOCT6100_API_CHANNEL pSecondChanEntry; + tPOCT6100_API_BIDIR_CHANNEL pBiDirChanEntry; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_BIDIR_CHANNEL_ENTRY_PNT( pSharedInfo, pBiDirChanEntry, f_usBiDirChanIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pFirstChanEntry, f_usFirstChanIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pSecondChanEntry, f_usSecondChanIndex ); + + /*=======================================================================*/ + /* Copy the channel's configuration and allocated resources. */ + + pFirstChanEntry->usExtraSinTsiMemIndex = f_usFirstChanExtraTsiIndex; + pFirstChanEntry->usSinCopyEventIndex = f_usFirstChanSinCopyEventIndex; + pFirstChanEntry->usSoutCopyEventIndex = f_usFirstChanSoutCopyEventIndex; + + pSecondChanEntry->usExtraSinTsiMemIndex = f_usSecondChanExtraTsiIndex; + pSecondChanEntry->usSinCopyEventIndex = f_usSecondChanSinCopyEventIndex; + pSecondChanEntry->usSoutCopyEventIndex = f_usSecondChanSoutCopyEventIndex; + + /* Save the channel info in the bidir channel.*/ + pBiDirChanEntry->usFirstChanIndex = f_usFirstChanIndex; + pBiDirChanEntry->usSecondChanIndex = f_usSecondChanIndex; + + + + /* Increment the extra TSI memory dependency count.*/ + + pFirstChanEntry->usExtraSinTsiDependencyCnt++; + pSecondChanEntry->usExtraSinTsiDependencyCnt++; + + /* Set the bidir flag in the channel structure.*/ + pFirstChanEntry->fBiDirChannel = TRUE; + pSecondChanEntry->fBiDirChannel = TRUE; + + /*=======================================================================*/ + + /* Form handle returned to user. */ + *f_pChannelCreateBiDir->pulBiDirChannelHndl = cOCT6100_HNDL_TAG_BIDIR_CHANNEL | (pBiDirChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_usBiDirChanIndex; + + /* Finally, mark the channel as open. */ + pBiDirChanEntry->fReserved = TRUE; + + /* Increment the number of channel open.*/ + f_pApiInstance->pSharedInfo->ChipStats.usNumberBiDirChannels++; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelDestroyBiDirSer + +Description: Closes a bidirectional channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelDestroyBiDir Pointer to a destroy bidirectionnal channel structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelDestroyBiDirSer +UINT32 Oct6100ChannelDestroyBiDirSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir ) +{ + UINT16 usBiDirChanIndex; + UINT16 usFirstChanIndex; + UINT16 usSecondChanIndex; + + + UINT32 ulResult; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertDestroyBiDirChanParams( f_pApiInstance, + f_pChannelDestroyBiDir, + &usBiDirChanIndex, + + &usFirstChanIndex, + &usSecondChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the echo cancellation channel. */ + ulResult = Oct6100ApiInvalidateBiDirChannelStructs( f_pApiInstance, + + usFirstChanIndex, + usSecondChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the echo cancellation channel. */ + ulResult = Oct6100ApiReleaseBiDirChannelResources( f_pApiInstance, + usBiDirChanIndex, + + usFirstChanIndex, + usSecondChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Invalidate the handle.*/ + f_pChannelDestroyBiDir->ulBiDirChannelHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertDestroyBiDirChanParams + +Description: Validate the handle given by the user and verify the state of + the channel about to be closed. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelDestroyBiDir Pointer to a destroy bidirectional channel structure. +f_pusBiDirChanIndex Pointer to the bidir channel entry within the API's list. +f_pusFirstChanIndex Pointer to the first channel index part of the bidir channel. +f_pusFirstChanIndex Pointer to the second channel index part of the bidir channel. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertDestroyBiDirChanParams +UINT32 Oct6100ApiAssertDestroyBiDirChanParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir, + IN OUT PUINT16 f_pusBiDirChanIndex, + + IN OUT PUINT16 f_pusFirstChanIndex, + IN OUT PUINT16 f_pusSecondChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BIDIR_CHANNEL pBiDirChanEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pChannelDestroyBiDir->ulBiDirChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_BIDIR_CHANNEL ) + return cOCT6100_ERR_CHANNEL_BIDIR_CHANNEL_HANDLE; + + *f_pusBiDirChanIndex = (UINT16)( f_pChannelDestroyBiDir->ulBiDirChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusBiDirChanIndex >= pSharedInfo->ChipConfig.usMaxBiDirChannels ) + return cOCT6100_ERR_CHANNEL_BIDIR_CHANNEL_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the bidir channel's list entry. */ + + mOCT6100_GET_BIDIR_CHANNEL_ENTRY_PNT( pSharedInfo, pBiDirChanEntry, *f_pusBiDirChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelDestroyBiDir->ulBiDirChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pBiDirChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_BIDIR_CHAN_NOT_OPEN; + if ( ulEntryOpenCnt != pBiDirChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_BIDIR_CHANNEL_HANDLE; + + /*=======================================================================*/ + + /* Return the index of the channel used to create this bidirectional channel.*/ + *f_pusFirstChanIndex = pBiDirChanEntry->usFirstChanIndex; + *f_pusSecondChanIndex = pBiDirChanEntry->usSecondChanIndex; + + + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInvalidateBiDirChannelStructs + +Description: Destroy the link between the two channels. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInvalidateBiDirChannelStructs +UINT32 Oct6100ApiInvalidateBiDirChannelStructs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + + IN UINT16 f_usFirstChanIndex, + IN UINT16 f_usSecondChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pFirstChanEntry; + tPOCT6100_API_CHANNEL pSecondChanEntry; + + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Get pointers to the API entry of the two channel used to create the bidir channel.*/ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pFirstChanEntry, f_usFirstChanIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pSecondChanEntry, f_usSecondChanIndex ); + + /* Clear the SIN copy event of the first channel and release the Extra TSI memory if + this feature was the only one using it. */ + + { + if ( pFirstChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + /*=======================================================================*/ + /* Clear the Sin Copy event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pFirstChanEntry->usSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Configure the TSST memory.*/ + if ( pFirstChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pFirstChanEntry->usSinTsstIndex, + pFirstChanEntry->usSinSoutTsiMemIndex, + pFirstChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pFirstChanEntry->usSinCopyEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + } + } + + /* Clear the SIN copy event of the first channel and release the Extra TSI memory if + this feature was the only one using it. */ + if ( pSecondChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + /*=======================================================================*/ + /* Clear the Sin Copy event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSecondChanEntry->usSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Configure the TSST memory.*/ + if ( pSecondChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pSecondChanEntry->usSinTsstIndex, + pSecondChanEntry->usSinSoutTsiMemIndex, + pSecondChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pSecondChanEntry->usSinCopyEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + } + + /* Now remove the sout copy of the first channel.*/ + + + { + /*=======================================================================*/ + /* Clear the Sout Copy event of the first channel.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pFirstChanEntry->usSoutCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*=======================================================================*/ + + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pFirstChanEntry->usSoutCopyEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + + + /* Now remove the sout copy of the second channel.*/ + + /*=======================================================================*/ + /* Clear the Sout Copy event of the second channel.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSecondChanEntry->usSoutCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*=======================================================================*/ + + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pSecondChanEntry->usSoutCopyEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseBiDirChannelResources + +Description: Release and clear the API entry associated to the bidirectional channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usBiDirChanIndex Index of the bidirectionnal channel in the API's bidir channel list. +f_usFirstChanIndex Index of the first channel used to create the bidir channel. +f_usSecondChanIndex Index of the second channel used to create the bidir channel. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseBiDirChannelResources +UINT32 Oct6100ApiReleaseBiDirChannelResources( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBiDirChanIndex, + + IN UINT16 f_usFirstChanIndex, + IN UINT16 f_usSecondChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BIDIR_CHANNEL pBiDirChanEntry; + tPOCT6100_API_CHANNEL pFirstChanEntry; + tPOCT6100_API_CHANNEL pSecondChanEntry; + tPOCT6100_API_MIXER_EVENT pTempEventEntry; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_BIDIR_CHANNEL_ENTRY_PNT( pSharedInfo, pBiDirChanEntry, f_usBiDirChanIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pFirstChanEntry, f_usFirstChanIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pSecondChanEntry, f_usSecondChanIndex ); + + /* Release the bidir entry.*/ + ulResult = Oct6100ApiReleaseBiDirChanEntry( f_pApiInstance, f_usBiDirChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_AC; + + /* Release the Extra TSI memory and the SIN copy event if required.*/ + + { + if ( pFirstChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + /* Release the two TSI chariot memory entries.*/ + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pFirstChanEntry->usExtraSinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A3; + + /* Relese the SIN copy event.*/ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pFirstChanEntry->usSinCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A4; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, pFirstChanEntry->usSinCopyEventIndex ); + + /* Invalidate the entry.*/ + pTempEventEntry->fReserved = FALSE; + pTempEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pTempEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + pFirstChanEntry->usExtraSinTsiDependencyCnt--; + pFirstChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + pFirstChanEntry->usSinCopyEventIndex = cOCT6100_INVALID_INDEX; + } + else + { + pFirstChanEntry->usExtraSinTsiDependencyCnt--; + } + } + + if ( pSecondChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + /* Release the two TSI chariot memory entries.*/ + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pSecondChanEntry->usExtraSinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A5; + + /* Relese the SIN copy event.*/ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pSecondChanEntry->usSinCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A6; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, pSecondChanEntry->usSinCopyEventIndex ); + /* Invalidate the entry.*/ + pTempEventEntry->fReserved = FALSE; + pTempEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pTempEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + pSecondChanEntry->usExtraSinTsiDependencyCnt--; + pSecondChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + pSecondChanEntry->usSinCopyEventIndex = cOCT6100_INVALID_INDEX; + } + else + { + pSecondChanEntry->usExtraSinTsiDependencyCnt--; + } + + + { + /* Release the SOUT copy event of the first channel.*/ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pFirstChanEntry->usSoutCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A7; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, pFirstChanEntry->usSoutCopyEventIndex ); + /* Invalidate the entry.*/ + pTempEventEntry->fReserved = FALSE; + pTempEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pTempEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + } + + /* Release the SOUT copy event of the second channel.*/ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pSecondChanEntry->usSoutCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A8; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, pSecondChanEntry->usSoutCopyEventIndex ); + /* Invalidate the entry.*/ + pTempEventEntry->fReserved = FALSE; + pTempEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pTempEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + + /*=======================================================================*/ + /* Update the first channel's list entry. */ + + /* Mark the channel as closed. */ + pFirstChanEntry->usSoutCopyEventIndex = cOCT6100_INVALID_INDEX; + pFirstChanEntry->fBiDirChannel = FALSE; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Update the second channel's list entry. */ + + /* Mark the channel as closed. */ + + pSecondChanEntry->usSoutCopyEventIndex = cOCT6100_INVALID_INDEX; + pSecondChanEntry->fBiDirChannel = FALSE; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Update the bidirectional channel's list entry. */ + + /* Mark the channel as closed. */ + pBiDirChanEntry->fReserved = FALSE; + pBiDirChanEntry->byEntryOpenCnt++; + + pBiDirChanEntry->usFirstChanIndex = cOCT6100_INVALID_INDEX; + pBiDirChanEntry->usSecondChanIndex = cOCT6100_INVALID_INDEX; + + /* Decrement the number of channel open.*/ + f_pApiInstance->pSharedInfo->ChipStats.usNumberBiDirChannels--; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Check if some of the ports must be muted back. */ + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, + f_usFirstChanIndex, + pFirstChanEntry->usRinTsstIndex, + pFirstChanEntry->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, + f_usSecondChanIndex, + pSecondChanEntry->usRinTsstIndex, + pSecondChanEntry->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ApiOctFloatToDbEnergyByte +INT32 Oct6100ApiOctFloatToDbEnergyByte(UINT8 x) +{ + INT32 lResult; + + lResult = Oct6100ApiOctFloatToDbEnergyHalf( (UINT16)(x << 8) ); + return lResult; +} +#endif + +#if !SKIP_Oct6100ApiOctFloatToDbEnergyHalf +INT32 Oct6100ApiOctFloatToDbEnergyHalf(UINT16 x) +{ + INT32 y; + UINT16 m; + + y = (((x >> 8) & 0x7F) - 0x41) * 3; + + m = (UINT16)((x & 0x00E0) >> 5); + if (m < 2) y += 0; + else if (m < 5) y += 1; + else y += 2; + + return y; +} +#endif + +#if !SKIP_Oct6100ApiDbAmpHalfToOctFloat +UINT16 Oct6100ApiDbAmpHalfToOctFloat(INT32 x) +{ + INT32 db_div6; + INT32 db_mod6; + UINT16 rval; + INT32 x_unsigned; + + if(x < 0) + { + x_unsigned = -x; + } + else + { + x_unsigned = x; + } + + db_div6 = x_unsigned / 6; + db_mod6 = x_unsigned % 6; + + if(x < 0) + { + if(db_mod6 == 0) + { + /* Change nothing! */ + db_div6 = -db_div6; + } + else + { + /* When we are negative, round down, and then adjust modulo. For example, if + x is -1, then db_div6 is 0 and db_mod6 is 1. We adjust so db_div6 = -1 and + db_mod6 = 5, which gives the correct adjustment. */ + db_div6 = -db_div6-1; + db_mod6 = 6 - db_mod6; + } + } + + rval = (UINT16)(0x4100 + db_div6 * 0x100); + + if(db_mod6 == 0) + { + rval += 0x0000; + } + else if(db_mod6 == 1) + { + rval += 0x0020; + } + else if(db_mod6 == 2) + { + rval += 0x0040; + } + else if(db_mod6 == 3) + { + rval += 0x0070; + } + else if(db_mod6 == 4) + { + rval += 0x0090; + } + else /* if(db_mod6 == 5) */ + { + rval += 0x00D0; + } + + return rval; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteDebugChanMemory + +Description: This function configure a debug channel echo memory entry + in internal memory.and external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pTdmConfig Pointer to a TDM configuration structure. +f_pVqeConfig Pointer to a VQE configuration structure. +f_pChannelOpen Pointer to a channel configuration structure. +f_usChanIndex Index of the echo channel in the API instance. +f_usEchoMemIndex Index of the echo channel within the SSPX memory. +f_usRinRoutTsiIndex RIN/ROUT TSI index within the TSI chariot memory. +f_usSinSoutTsiIndex SIN/SOUT TSI index within the TSI chariot memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteDebugChanMemory +UINT32 Oct6100ApiWriteDebugChanMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_TDM f_pTdmConfig, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN UINT16 f_usRinRoutTsiIndex, + IN UINT16 f_usSinSoutTsiIndex ) +{ + UINT32 ulResult; + + /*==============================================================================*/ + /* Write the VQE configuration of the debug channel. */ + + ulResult = Oct6100ApiWriteVqeMemory( + f_pApiInstance, + f_pVqeConfig, + f_pChannelOpen, + f_usChanIndex, + f_usEchoMemIndex, + TRUE, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + /*==============================================================================*/ + + /* Write the echo memory configuration of the debug channel. */ + ulResult = Oct6100ApiWriteEchoMemory( + f_pApiInstance, + f_pTdmConfig, + f_pChannelOpen, + f_usEchoMemIndex, + f_usRinRoutTsiIndex, + f_usSinSoutTsiIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiDebugChannelOpen + +Description: Internal function used to open a debug channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiDebugChannelOpen +UINT32 Oct6100ApiDebugChannelOpen( + IN tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_CHANNEL_OPEN TempChanOpen; + + UINT32 ulResult; + UINT16 usChanIndex; + UINT16 usDummyEchoIndex; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Let's program the channel memory.*/ + Oct6100ChannelOpenDef( &TempChanOpen ); + + TempChanOpen.ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_HT_RESET; /* Activate the channel in reset.*/ + TempChanOpen.VqeConfig.fEnableNlp = FALSE; + TempChanOpen.VqeConfig.ulComfortNoiseMode = cOCT6100_COMFORT_NOISE_NORMAL; + TempChanOpen.VqeConfig.fSinDcOffsetRemoval = FALSE; + TempChanOpen.VqeConfig.fRinDcOffsetRemoval = FALSE; + TempChanOpen.VqeConfig.lDefaultErlDb = 0; + + /* Loop to reserve the proper entry for the debug channel */ + for( usChanIndex = 0; usChanIndex < ( pSharedInfo->DebugInfo.usRecordChanIndex + 1 ); usChanIndex ++ ) + { + ulResult = Oct6100ApiReserveEchoEntry( f_pApiInstance, &usDummyEchoIndex ); + if( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Loop to free all entries except the one for the debug channel */ + for( usChanIndex = pSharedInfo->DebugInfo.usRecordChanIndex; usChanIndex > 0; ) + { + usChanIndex--; + ulResult = Oct6100ApiReleaseEchoEntry( f_pApiInstance, usChanIndex ); + if( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + ulResult = Oct6100ApiWriteDebugChanMemory( f_pApiInstance, + &TempChanOpen.TdmConfig, + &TempChanOpen.VqeConfig, + &TempChanOpen, + pSharedInfo->DebugInfo.usRecordChanIndex, + pSharedInfo->DebugInfo.usRecordMemIndex, + pSharedInfo->DebugInfo.usRecordRinRoutTsiMemIndex, + pSharedInfo->DebugInfo.usRecordSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiMuteChannelPort + +Description: This function will verify if a input TSST is bound to the RIN and + SIN port. If not, the port will be muted. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiMutePorts +UINT32 Oct6100ApiMutePorts( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEchoIndex, + IN UINT16 f_usRinTsstIndex, + IN UINT16 f_usSinTsstIndex, + IN BOOL f_fCheckBridgeIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usEchoIndex ); + + /* Mute the Rin port. */ + if ( ( f_fCheckBridgeIndex == FALSE ) + || ( ( f_fCheckBridgeIndex == TRUE ) && ( pChanEntry->usBridgeIndex == cOCT6100_INVALID_INDEX ) ) ) + { + /* If the channel is in bidir mode, do not create the Rin silence event!!! */ + if ( pChanEntry->fBiDirChannel == FALSE ) + { + if ( ( ( f_usRinTsstIndex == cOCT6100_INVALID_INDEX ) || ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_RIN ) != 0x0 ) ) + && ( pChanEntry->usRinSilenceEventIndex == cOCT6100_INVALID_INDEX ) ) + { + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, + &pChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now, write the mixer event used to copy the RIN signal of the silence channel + into the RIN signal of the current channel. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pChanEntry->usRinSilenceEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= 1534; + WriteParams.usWriteData |= cOCT6100_PCM_U_LAW << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pChanEntry->usRinRoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Now insert the Sin copy event into the list.*/ + + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + pChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY, + f_usEchoIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Mute the Sin port. */ + if ( ( ( f_usSinTsstIndex == cOCT6100_INVALID_INDEX ) || ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN ) != 0x0 ) ) + && ( pChanEntry->usSinSilenceEventIndex == cOCT6100_INVALID_INDEX ) ) + { + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, + &pChanEntry->usSinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now, write the mixer event used to copy the SIN signal of the silence channel + into the SIN signal of the current channel. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pChanEntry->usSinSilenceEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= 1534; + WriteParams.usWriteData |= cOCT6100_PCM_U_LAW << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pChanEntry->usSinSoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Now insert the Sin copy event into the list.*/ + + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + pChanEntry->usSinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY, + f_usEchoIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Unmute the Rin port if it was muted. */ + if ( ( ( f_usRinTsstIndex != cOCT6100_INVALID_INDEX ) && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_RIN ) == 0x0 ) ) + && ( pChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_E1; + + pChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + + /* Unmute the Sin port if it was muted. */ + if ( ( ( f_usSinTsstIndex != cOCT6100_INVALID_INDEX ) && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN ) == 0x0 ) ) + && ( pChanEntry->usSinSilenceEventIndex != cOCT6100_INVALID_INDEX ) ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pChanEntry->usSinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pChanEntry->usSinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_E2; + + pChanEntry->usSinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiSetChannelLevelControl + +Description: This function will configure the level control on a given + channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pVqeConfig VQE config of the channel. +f_usChanIndex Index of the channel within the API instance. +f_usEchoMemIndex Index of the echo channel within the SSPX memory. +f_fClearAlcHlcStatusBit If this is set, the ALC-HLC status bit must be + incremented. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiSetChannelLevelControl +UINT32 Oct6100ApiSetChannelLevelControl( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fClearAlcHlcStatusBit ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + UINT32 ulTempData; + UINT32 ulBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulMask; + UINT32 i; + UINT16 usTempData; + UINT8 byLastStatus; + BOOL fDisableAlcFirst; + + /* Get local pointer to shared portion of the API instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a pointer to the channel list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ); + + /* Before doing anything, check if the configuration has changed. */ + if ( ( f_fClearAlcHlcStatusBit == TRUE ) + || ( f_pVqeConfig->fRinLevelControl != pChanEntry->VqeConfig.fRinLevelControl ) + || ( f_pVqeConfig->lRinLevelControlGainDb != pChanEntry->VqeConfig.chRinLevelControlGainDb ) + || ( f_pVqeConfig->fRinAutomaticLevelControl != pChanEntry->VqeConfig.fRinAutomaticLevelControl ) + || ( f_pVqeConfig->lRinAutomaticLevelControlTargetDb != pChanEntry->VqeConfig.chRinAutomaticLevelControlTargetDb ) + || ( f_pVqeConfig->fRinHighLevelCompensation != pChanEntry->VqeConfig.fRinHighLevelCompensation ) + || ( f_pVqeConfig->lRinHighLevelCompensationThresholdDb != pChanEntry->VqeConfig.chRinHighLevelCompensationThresholdDb ) + || ( f_pVqeConfig->fSoutLevelControl != pChanEntry->VqeConfig.fSoutLevelControl ) + || ( f_pVqeConfig->lSoutLevelControlGainDb != pChanEntry->VqeConfig.chSoutLevelControlGainDb ) + || ( f_pVqeConfig->fSoutAutomaticLevelControl != pChanEntry->VqeConfig.fSoutAutomaticLevelControl ) + || ( f_pVqeConfig->lSoutAutomaticLevelControlTargetDb != pChanEntry->VqeConfig.chSoutAutomaticLevelControlTargetDb ) + || ( f_pVqeConfig->fSoutNaturalListenerEnhancement != pChanEntry->VqeConfig.fSoutNaturalListenerEnhancement ) + || ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb != pChanEntry->VqeConfig.bySoutAutomaticListenerEnhancementGainDb ) + || ( f_pVqeConfig->ulSoutNaturalListenerEnhancementGainDb != pChanEntry->VqeConfig.bySoutNaturalListenerEnhancementGainDb ) ) + { + /* Calculate base address for manual level control configuration. */ + ulBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + + /* Set the Level control on RIN port.*/ + ulFeatureBytesOffset = pSharedInfo->MemoryMap.RinLevelControlOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.RinLevelControlOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.RinLevelControlOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( ( f_pVqeConfig->fRinLevelControl == TRUE ) + || ( f_pVqeConfig->fRinAutomaticLevelControl == TRUE ) + || ( f_pVqeConfig->fRinHighLevelCompensation == TRUE ) ) + { + /* Set the level control value.*/ + if ( ( f_pVqeConfig->fRinAutomaticLevelControl == TRUE ) + || ( f_pVqeConfig->fRinHighLevelCompensation == TRUE ) ) + ulTempData |= ( 0xFF << ulFeatureBitOffset ); + else + { + /* Convert the dB value into OctFloat format.*/ + usTempData = Oct6100ApiDbAmpHalfToOctFloat( f_pVqeConfig->lRinLevelControlGainDb ); + usTempData -= 0x3800; + usTempData &= 0x0FF0; + usTempData >>= 4; + + ulTempData |= ( usTempData << ulFeatureBitOffset ); + } + } + else /* ( ( f_pVqeConfig->fRinLevelControl == FALSE ) && ( f_pVqeConfig->fRinAutomaticLevelControl == FALSE ) && ( f_pVqeConfig->fRinHighLevelCompensation == FALSE ) ) */ + { + ulTempData |= ( cOCT6100_PASS_THROUGH_LEVEL_CONTROL << ulFeatureBitOffset ); + } + + /* Save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the Level control on SOUT port.*/ + ulFeatureBytesOffset = pSharedInfo->MemoryMap.SoutLevelControlOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.SoutLevelControlOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.SoutLevelControlOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( ( f_pVqeConfig->fSoutLevelControl == TRUE ) + || ( f_pVqeConfig->fSoutAutomaticLevelControl == TRUE ) + || ( f_pVqeConfig->fSoutNaturalListenerEnhancement == TRUE ) + || ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb != 0x0 ) ) + { + /* Set the level control value.*/ + if ( ( f_pVqeConfig->fSoutAutomaticLevelControl == TRUE ) + || ( f_pVqeConfig->fSoutNaturalListenerEnhancement == TRUE ) + || ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb != 0x0 ) ) + ulTempData |= ( 0xFF << ulFeatureBitOffset ); + else + { + /* Convert the dB value into OctFloat format.*/ + usTempData = Oct6100ApiDbAmpHalfToOctFloat( f_pVqeConfig->lSoutLevelControlGainDb ); + usTempData -= 0x3800; + usTempData &= 0x0FF0; + usTempData >>= 4; + + ulTempData |= ( usTempData << ulFeatureBitOffset ); + } + } + else + { + ulTempData |= ( cOCT6100_PASS_THROUGH_LEVEL_CONTROL << ulFeatureBitOffset ); + } + + /* Save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Calculate base address for auto level control + high level compensation configuration. */ + ulBaseAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoMemIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst; + + /* Check which one is to be disabled first. */ + if ( f_pVqeConfig->fRinAutomaticLevelControl == TRUE ) + fDisableAlcFirst = FALSE; + else + fDisableAlcFirst = TRUE; + + for ( i = 0; i < 2; i ++ ) + { + /* Set the auto level control target Db for the Rin port. */ + if ( ( ( i == 0 ) && ( fDisableAlcFirst == TRUE ) ) || ( ( i == 1 ) && ( fDisableAlcFirst == FALSE ) ) ) + { + if ( pSharedInfo->ImageInfo.fRinAutoLevelControl == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.RinAutoLevelControlTargetOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.RinAutoLevelControlTargetOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.RinAutoLevelControlTargetOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( f_pVqeConfig->fRinAutomaticLevelControl == TRUE ) + { + /* Convert the dB value into OctFloat format.*/ + usTempData = Oct6100ApiDbAmpHalfToOctFloat( 2 * f_pVqeConfig->lRinAutomaticLevelControlTargetDb ); + + /* Set auto level control target on the Rin port. */ + ulTempData |= ( usTempData << ulFeatureBitOffset ); + } + else /* if ( f_pVqeConfig->fRinAutomaticLevelControl == FALSE ) */ + { + /* Disable auto level control. */ + ulTempData |= ( 0xFFFF << ulFeatureBitOffset ); + } + + /* Save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else + { + /* Set the high level compensation threshold Db for the Rin port. */ + if ( pSharedInfo->ImageInfo.fRinHighLevelCompensation == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.RinHighLevelCompensationThresholdOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.RinHighLevelCompensationThresholdOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.RinHighLevelCompensationThresholdOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( f_pVqeConfig->fRinHighLevelCompensation == TRUE ) + { + /* Convert the dB value into OctFloat format.*/ + usTempData = Oct6100ApiDbAmpHalfToOctFloat( 2 * f_pVqeConfig->lRinHighLevelCompensationThresholdDb ); + + /* Set high level compensation threshold on the Rin port. */ + ulTempData |= ( usTempData << ulFeatureBitOffset ); + } + else /* if ( f_pVqeConfig->fRinHighLevelCompensation == FALSE ) */ + { + /* Disable high level compensation. */ + ulTempData |= ( 0xFFFF << ulFeatureBitOffset ); + } + + /* Save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Set the auto level control target Db for the Sout port. */ + if ( pSharedInfo->ImageInfo.fRinAutoLevelControl == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.SoutAutoLevelControlTargetOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.SoutAutoLevelControlTargetOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.SoutAutoLevelControlTargetOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( f_pVqeConfig->fSoutAutomaticLevelControl == TRUE ) + { + /* Convert the dB value into OctFloat format.*/ + usTempData = Oct6100ApiDbAmpHalfToOctFloat( 2 * f_pVqeConfig->lSoutAutomaticLevelControlTargetDb ); + + /* Set auto level control target on the Sout port. */ + ulTempData |= ( usTempData << ulFeatureBitOffset ); + } + else /* if ( f_pVqeConfig->fSoutAutomaticLevelControl == FALSE ) */ + { + /* Disable auto level control. */ + ulTempData |= ( 0xFFFF << ulFeatureBitOffset ); + } + + /* Save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Set the high level compensation threshold Db for the Sout port. */ + if ( pSharedInfo->ImageInfo.fSoutHighLevelCompensation == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.SoutHighLevelCompensationThresholdOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.SoutHighLevelCompensationThresholdOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.SoutHighLevelCompensationThresholdOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Disable high level compensation on Sout for now. */ + ulTempData |= ( 0xFFFF << ulFeatureBitOffset ); + + /* Save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Check if have to clear the ALC-HLC status. */ + if ( ( pSharedInfo->ImageInfo.fAlcHlcStatus == TRUE ) + && ( ( f_fClearAlcHlcStatusBit == TRUE ) + + ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AlcHlcStatusOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AlcHlcStatusOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AlcHlcStatusOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Get previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + /* Retrieve last status. */ + byLastStatus = (UINT8)( ( ( ulTempData & ulMask ) >> ulFeatureBitOffset ) & 0xFF ); + + /* Increment to reset context. */ + byLastStatus ++; + + /* Just in case, not to overwrite some context in external memory. */ + byLastStatus &= ( 0x1 << ulFeatureFieldLength ) - 1; + + /* Clear last status. */ + ulTempData &= (~ulMask); + + /* Set new status. */ + ulTempData |= ( byLastStatus << ulFeatureBitOffset ); + + /* Save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiSetChannelTailConfiguration + +Description: This function will configure the tail displacement and length + on a given channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pVqeConfig VQE config of the channel. +f_usChanIndex Index of the channel within the API instance. +f_usEchoMemIndex Index of the echo channel within the SSPX memory. +f_fModifyOnly Function called from a modify or open? + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiSetChannelTailConfiguration +UINT32 Oct6100ApiSetChannelTailConfiguration( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fModifyOnly ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + UINT32 ulTempData; + UINT32 ulNlpConfBaseAddress; + UINT32 ulAfConfBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulMask; + UINT32 ulTailSum; + BOOL fTailDisplacementModified = FALSE; + + /* Get local pointer to shared portion of the API instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a pointer to the channel list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ); + + /* Calculate base addresses of NLP + AF configuration structure for the specified channel. */ + ulNlpConfBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + ulAfConfBaseAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoMemIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainIoMemOfst; + + /* Set the tail displacement.*/ + if ( pSharedInfo->ImageInfo.fTailDisplacement == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->fEnableTailDisplacement != pChanEntry->VqeConfig.fEnableTailDisplacement ) + || ( f_pVqeConfig->ulTailDisplacement != pChanEntry->VqeConfig.usTailDisplacement ) + || ( f_pVqeConfig->fAcousticEcho != pChanEntry->VqeConfig.fAcousticEcho ) ) ) ) + { + /* Remember that the tail displacement parameters were changed. */ + fTailDisplacementModified = TRUE; + + /* Check if we must set the tail displacement value. */ + if ( ( f_pVqeConfig->fEnableTailDisplacement == TRUE ) + && ( pSharedInfo->ImageInfo.fPerChannelTailDisplacement == TRUE ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.PerChanTailDisplacementFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.PerChanTailDisplacementFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.PerChanTailDisplacementFieldOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + if ( ( f_pVqeConfig->fEnableTailDisplacement == TRUE ) + && ( f_pVqeConfig->ulTailDisplacement != 0x0 ) ) + { + if ( pSharedInfo->ImageInfo.fAfTailDisplacement == FALSE ) + { + if ( f_pVqeConfig->ulTailDisplacement == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTempData |= ( ( ( pSharedInfo->ChipConfig.usTailDisplacement / 16 ) ) << ulFeatureBitOffset ); + } + else + { + ulTempData |= ( ( ( f_pVqeConfig->ulTailDisplacement / 16 ) ) << ulFeatureBitOffset ); + } + } + else /* if ( pSharedInfo->ImageInfo.fAfTailDisplacement == TRUE ) */ + { + /* If AEC is not activated, this must be set to the requested tail displacement. */ + if ( f_pVqeConfig->fAcousticEcho == FALSE ) + { + if ( f_pVqeConfig->ulTailDisplacement == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTailSum = pSharedInfo->ChipConfig.usTailDisplacement; + } + else + { + ulTailSum = f_pVqeConfig->ulTailDisplacement; + } + + if ( ulTailSum == 0 ) + { + ulTempData |= ( ( 0 ) << ulFeatureBitOffset ); + } + else if ( ulTailSum <= 128 ) + { + ulTempData |= ( ( 1 ) << ulFeatureBitOffset ); + } + else if ( ulTailSum <= 384 ) + { + ulTempData |= ( ( 3 ) << ulFeatureBitOffset ); + } + else /* if ( ulTailSum <= 896 ) */ + { + ulTempData |= ( ( 7 ) << ulFeatureBitOffset ); + } + } + else /* if ( f_pVqeConfig->fAcousticEcho == FALSE ) */ + { + /* Otherwise, the tail displacement is configured differently. This field stays to 0. */ + ulTempData |= ( 0x0 << ulFeatureBitOffset ); + } + } + } + + /* Then save the new DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pSharedInfo->ImageInfo.fAfTailDisplacement == TRUE ) + { + /* Set the tail displacement offset in the AF. */ + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AfTailDisplacementFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AfTailDisplacementFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AfTailDisplacementFieldOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( f_pVqeConfig->ulTailDisplacement == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTempData |= ( ( ( pSharedInfo->ChipConfig.usTailDisplacement / 16 ) ) << ulFeatureBitOffset ); + } + else + { + ulTempData |= ( ( ( f_pVqeConfig->ulTailDisplacement / 16 ) ) << ulFeatureBitOffset ); + } + + /* Then save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + ulFeatureBytesOffset = pSharedInfo->MemoryMap.TailDisplEnableOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.TailDisplEnableOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.TailDisplEnableOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + ulTempData |= ( ( (UINT32)f_pVqeConfig->fEnableTailDisplacement ) << ulFeatureBitOffset ); + + /* Then save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the tail length. */ + if ( pSharedInfo->ImageInfo.fPerChannelTailLength == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->ulTailLength != pChanEntry->VqeConfig.usTailLength ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.PerChanTailLengthFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.PerChanTailLengthFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.PerChanTailLengthFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + /* Check if must automatically select maximum or if must use user specific value. */ + if ( f_pVqeConfig->ulTailLength == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTempData |= ( ( ( pSharedInfo->ImageInfo.usMaxTailLength - 32 ) / 4 ) << ulFeatureBitOffset ); + } + else + { + ulTempData |= ( ( ( f_pVqeConfig->ulTailLength - 32 ) / 4 ) << ulFeatureBitOffset ); + } + + /* Then save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Configure AEC tail length. */ + if ( pSharedInfo->ImageInfo.fAecTailLength == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( fTailDisplacementModified == TRUE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->ulAecTailLength != pChanEntry->VqeConfig.usAecTailLength ) + || ( f_pVqeConfig->fAcousticEcho != pChanEntry->VqeConfig.fAcousticEcho ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AecTailLengthFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AecTailLengthFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AecTailLengthFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set acoustic echo tail length. */ + if ( f_pVqeConfig->fAcousticEcho == TRUE ) + { + switch( f_pVqeConfig->ulAecTailLength ) + { + case 1024: + ulTempData |= ( ( 3 ) << ulFeatureBitOffset ); + break; + case 512: + ulTempData |= ( ( 2 ) << ulFeatureBitOffset ); + break; + case 256: + ulTempData |= ( ( 1 ) << ulFeatureBitOffset ); + break; + case 128: + default: + ulTempData |= ( ( 0 ) << ulFeatureBitOffset ); + break; + } + } + else if ( f_pVqeConfig->fEnableTailDisplacement == TRUE ) + { + /* No acoustic echo case. */ + + /* Start with requested tail displacement. */ + if ( f_pVqeConfig->ulTailDisplacement == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTailSum = pSharedInfo->ChipConfig.usTailDisplacement; + } + else + { + ulTailSum = f_pVqeConfig->ulTailDisplacement; + } + + /* Add requested tail length. */ + if ( f_pVqeConfig->ulTailLength == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTailSum += pSharedInfo->ImageInfo.usMaxTailLength; + } + else + { + ulTailSum += f_pVqeConfig->ulTailLength; + } + + /* Round this value up. */ + if ( ulTailSum <= 128 ) + { + ulTempData |= ( ( 0 ) << ulFeatureBitOffset ); + } + else if ( ulTailSum <= 256 ) + { + ulTempData |= ( ( 1 ) << ulFeatureBitOffset ); + } + else if ( ulTailSum <= 512 ) + { + ulTempData |= ( ( 2 ) << ulFeatureBitOffset ); + } + else /* if ( ulTailSum <= 1024 ) */ + { + ulTempData |= ( ( 3 ) << ulFeatureBitOffset ); + } + } + else + { + /* Keep this to zero. */ + ulTempData |= ( ( 0 ) << ulFeatureBitOffset ); + } + + /* Write the new DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelMuteSer + +Description: This function will mute some of the ports on a given + channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelMute What channel/ports to mute. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelMuteSer +UINT32 Oct6100ChannelMuteSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MUTE f_pChannelMute ) +{ + UINT32 ulResult; + UINT16 usChanIndex; + UINT16 usPortMask; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertChannelMuteParams( f_pApiInstance, + f_pChannelMute, + &usChanIndex, + &usPortMask ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Call the actual channel mute ports function. */ + ulResult = Oct6100ApiMuteChannelPorts( f_pApiInstance, + usChanIndex, + usPortMask, + TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertChannelMuteParams + +Description: Check the user parameters passed to the channel mute function. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelMute What channel/ports to mute. +f_pusChanIndex Resulting channel index where the muting should + be applied. +f_pusPorts Port mask on which to apply the muting. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertChannelMuteParams +UINT32 Oct6100ApiAssertChannelMuteParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MUTE f_pChannelMute, + OUT PUINT16 f_pusChanIndex, + OUT PUINT16 f_pusPorts ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pChannelMute->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + *f_pusChanIndex = (UINT16)( f_pChannelMute->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, *f_pusChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelMute->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + if ( pChanEntry->fBiDirChannel == TRUE ) + return cOCT6100_ERR_CHANNEL_PART_OF_BIDIR_CHANNEL; + + /*=======================================================================*/ + + /* Check the provided port mask. */ + + if ( ( f_pChannelMute->ulPortMask & + ~( cOCT6100_CHANNEL_MUTE_PORT_NONE | + cOCT6100_CHANNEL_MUTE_PORT_RIN | + cOCT6100_CHANNEL_MUTE_PORT_ROUT | + cOCT6100_CHANNEL_MUTE_PORT_SIN | + cOCT6100_CHANNEL_MUTE_PORT_SOUT | + cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) ) != 0 ) + return cOCT6100_ERR_CHANNEL_MUTE_MASK; + + /* Sin + Sin with features cannot be muted simultaneously. */ + if ( ( ( f_pChannelMute->ulPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN ) != 0x0 ) + && ( ( f_pChannelMute->ulPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) ) + return cOCT6100_ERR_CHANNEL_MUTE_MASK_SIN; + + /* Check if Sin mute with features is supported by the firmware. */ + if ( ( ( f_pChannelMute->ulPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) + && ( pSharedInfo->ImageInfo.fSinMute == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SIN_MUTE_FEATURES; + + /* Return the ports to the calling function. */ + *f_pusPorts = (UINT16)( f_pChannelMute->ulPortMask & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelUnMuteSer + +Description: This function will unmute some of the ports on a given + channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelUnMute What channel/ports to unmute. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelUnMuteSer +UINT32 Oct6100ChannelUnMuteSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute ) +{ + UINT32 ulResult; + UINT16 usChanIndex; + UINT16 usPortMask; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertChannelUnMuteParams( f_pApiInstance, + f_pChannelUnMute, + &usChanIndex, + &usPortMask ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Call the actual channel mute ports function. */ + ulResult = Oct6100ApiMuteChannelPorts( f_pApiInstance, + usChanIndex, + usPortMask, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertChannelUnMuteParams + +Description: Check the user parameters passed to the channel unmute function. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelUnMute What channel/ports to Unmute. +f_pusChanIndex Resulting channel index where the muting should + be applied. +f_pusPorts Port mask on which to apply the muting. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertChannelUnMuteParams +UINT32 Oct6100ApiAssertChannelUnMuteParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute, + OUT PUINT16 f_pusChanIndex, + OUT PUINT16 f_pusPorts ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pChannelUnMute->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + *f_pusChanIndex = (UINT16)( f_pChannelUnMute->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, *f_pusChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelUnMute->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + if ( pChanEntry->fBiDirChannel == TRUE ) + return cOCT6100_ERR_CHANNEL_PART_OF_BIDIR_CHANNEL; + + /*=======================================================================*/ + + /* Check the provided port mask. */ + + if ( ( f_pChannelUnMute->ulPortMask & + ~( cOCT6100_CHANNEL_MUTE_PORT_NONE | + cOCT6100_CHANNEL_MUTE_PORT_RIN | + cOCT6100_CHANNEL_MUTE_PORT_ROUT | + cOCT6100_CHANNEL_MUTE_PORT_SIN | + cOCT6100_CHANNEL_MUTE_PORT_SOUT | + cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) ) != 0 ) + return cOCT6100_ERR_CHANNEL_MUTE_MASK; + + /* Return the ports to the calling function. */ + *f_pusPorts = (UINT16)( f_pChannelUnMute->ulPortMask & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiMuteSinWithFeatures + +Description: Mute or Unmute the sin with features port. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usChanIndex Resulting channel index where the muting should + be applied. +f_fEnableSinWithFeatures Whether to enable the feature or not. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiMuteSinWithFeatures +UINT32 Oct6100ApiMuteSinWithFeatures( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChanIndex, + IN BOOL f_fEnableSinWithFeatures ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + UINT32 ulTempData; + UINT32 ulBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulMask; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ) + + ulBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( pChanEntry->usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + + if ( pSharedInfo->ImageInfo.fSinMute == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.SinMuteOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.SinMuteOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.SinMuteOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + /* Clear the mute flag. */ + ulTempData &= (~ulMask); + + /* Set the mute flag on the Sin port.*/ + if ( f_fEnableSinWithFeatures == TRUE ) + ulTempData |= ( 0x1 << ulFeatureBitOffset ); + + /* Write the new DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiMuteChannelPorts + +Description: Mute or Unmute the specified ports, according to the mask. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usChanIndex Resulting channel index where the muting should + be applied. +f_usPortMask Port mask on which to apply the muting/unmuting. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiMuteChannelPorts +UINT32 Oct6100ApiMuteChannelPorts( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChanIndex, + IN UINT16 f_usPortMask, + IN BOOL f_fMute ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + BOOL fDisableSinWithFeatures = FALSE; + BOOL fEnableSinWithFeatures = FALSE; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ) + + /* Rin port. */ + if ( ( f_fMute == TRUE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_RIN ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_RIN ) == 0x0 ) ) + { + /* Mute this port. */ + pChanEntry->usMutedPorts |= cOCT6100_CHANNEL_MUTE_PORT_RIN; + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, f_usChanIndex, pChanEntry->usRinTsstIndex, pChanEntry->usSinTsstIndex, TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + { + pChanEntry->usMutedPorts &= ~cOCT6100_CHANNEL_MUTE_PORT_RIN; + return ulResult; + } + } + else if ( ( f_fMute == FALSE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_RIN ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_RIN ) != 0x0 ) ) + { + /* Unmute this port. */ + pChanEntry->usMutedPorts &= ~cOCT6100_CHANNEL_MUTE_PORT_RIN; + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, f_usChanIndex, pChanEntry->usRinTsstIndex, pChanEntry->usSinTsstIndex, TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Rout port. */ + if ( ( f_fMute == TRUE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_ROUT ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_ROUT ) == 0x0 ) ) + { + /* Mute this port. */ + + if ( pChanEntry->usRoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + pChanEntry->usRoutTsstIndex, + pChanEntry->CodecConfig.byAdpcmNibblePosition, + pChanEntry->TdmConfig.byRoutNumTssts, + 1534 ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + pChanEntry->usMutedPorts |= cOCT6100_CHANNEL_MUTE_PORT_ROUT; + } + else if ( ( f_fMute == FALSE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_ROUT ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_ROUT ) != 0x0 ) ) + { + /* Unmute this port. */ + + if ( pChanEntry->usRoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + pChanEntry->usRoutTsstIndex, + pChanEntry->CodecConfig.byAdpcmNibblePosition, + pChanEntry->TdmConfig.byRoutNumTssts, + pChanEntry->usRinRoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + pChanEntry->usMutedPorts &= ~cOCT6100_CHANNEL_MUTE_PORT_ROUT; + } + + /* Sin port. */ + if ( ( f_fMute == TRUE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN ) == 0x0 ) ) + { + /* Mute this port. */ + pChanEntry->usMutedPorts |= cOCT6100_CHANNEL_MUTE_PORT_SIN; + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, f_usChanIndex, pChanEntry->usRinTsstIndex, pChanEntry->usSinTsstIndex, TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + { + pChanEntry->usMutedPorts &= ~cOCT6100_CHANNEL_MUTE_PORT_SIN; + return ulResult; + } + } + else if ( + ( ( f_fMute == FALSE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN ) != 0x0 ) ) + || + ( ( f_fMute == TRUE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN ) != 0x0 ) ) ) + { + /* Unmute this port. */ + pChanEntry->usMutedPorts &= ~cOCT6100_CHANNEL_MUTE_PORT_SIN; + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, f_usChanIndex, pChanEntry->usRinTsstIndex, pChanEntry->usSinTsstIndex, TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Sout port. */ + if ( ( f_fMute == TRUE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SOUT ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SOUT ) == 0x0 ) ) + { + /* Mute this port. */ + + if ( pChanEntry->usSoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + pChanEntry->usSoutTsstIndex, + pChanEntry->CodecConfig.byAdpcmNibblePosition, + pChanEntry->TdmConfig.bySoutNumTssts, + 1534 ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + pChanEntry->usMutedPorts |= cOCT6100_CHANNEL_MUTE_PORT_SOUT; + } + else if ( ( f_fMute == FALSE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SOUT ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SOUT ) != 0x0 ) ) + { + /* Unmute this port. */ + + if ( pChanEntry->usSoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + pChanEntry->usSoutTsstIndex, + pChanEntry->CodecConfig.byAdpcmNibblePosition, + pChanEntry->TdmConfig.bySoutNumTssts, + pChanEntry->usSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + pChanEntry->usMutedPorts &= ~cOCT6100_CHANNEL_MUTE_PORT_SOUT; + } + + /* Sin with features port. */ + if ( ( f_fMute == TRUE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) == 0x0 ) ) + { + /* Mute this port. */ + pChanEntry->usMutedPorts |= cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES; + fEnableSinWithFeatures = TRUE; + } + else if ( + ( ( f_fMute == FALSE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) ) + || + ( ( f_fMute == TRUE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) ) ) + { + /* Unmute this port. */ + pChanEntry->usMutedPorts &= ~cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES; + + fDisableSinWithFeatures = TRUE; + } + + /* Check if must enable or disable SIN mute with features. */ + if ( fDisableSinWithFeatures == TRUE || fEnableSinWithFeatures == TRUE ) + { + ulResult = Oct6100ApiMuteSinWithFeatures( f_pApiInstance, f_usChanIndex, fEnableSinWithFeatures ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.c new file mode 100644 index 0000000..0303688 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.c @@ -0,0 +1,6899 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_open.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the functions used to power-up the chip according to the + user's configuration. Also, the API instance is initialized to reflect the + desired configuration. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 347 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#if defined(__FreeBSD__) +#include +#include +#else +#ifndef __KERNEL__ +#include +#define kmalloc(size, type) malloc(size) +#define kfree(ptr) free(ptr) +#define GFP_ATOMIC 0 /*Dummy */ +#else +#include +#include +#endif +#endif + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" + +#include "apilib/octapi_bt0.h" +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_tsi_cnct_inst.h" +#include "oct6100api/oct6100_events_inst.h" +#include "oct6100api/oct6100_conf_bridge_inst.h" +#include "oct6100api/oct6100_playout_buf_inst.h" + +#include "oct6100api/oct6100_mixer_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_adpcm_chan_inst.h" +#include "oct6100api/oct6100_phasing_tsst_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_api_inst.h" + +#include "oct6100api/oct6100_chip_stats_pub.h" +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_tsi_cnct_pub.h" +#include "oct6100api/oct6100_events_pub.h" +#include "oct6100api/oct6100_conf_bridge_pub.h" +#include "oct6100api/oct6100_playout_buf_pub.h" + +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_adpcm_chan_pub.h" +#include "oct6100api/oct6100_phasing_tsst_pub.h" +#include "oct6100api/oct6100_remote_debug_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_mixer_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_debug_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_interrupts_priv.h" +#include "oct6100_chip_stats_priv.h" +#include "octrpc/rpc_protocol.h" +#include "oct6100_remote_debug_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_tsst_priv.h" +#include "oct6100_tsi_cnct_priv.h" +#include "oct6100_mixer_priv.h" +#include "oct6100_events_priv.h" +#include "oct6100_conf_bridge_priv.h" +#include "oct6100_playout_buf_priv.h" + +#include "oct6100_channel_priv.h" +#include "oct6100_adpcm_chan_priv.h" +#include "oct6100_phasing_tsst_priv.h" +#include "oct6100_tlv_priv.h" +#include "oct6100_debug_priv.h" +#include "oct6100_version.h" + + +/**************************** PUBLIC FUNCTIONS *****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100GetInstanceSizeDef + +Description: Retrieves the size of the required API instance structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pGetSize Structure containing API instance size. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100GetInstanceSizeDef +UINT32 Oct6100GetInstanceSizeDef( + tPOCT6100_GET_INSTANCE_SIZE f_pGetSize ) +{ + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100GetInstanceSize +UINT32 Oct6100GetInstanceSize( + tPOCT6100_CHIP_OPEN f_pChipOpen, + tPOCT6100_GET_INSTANCE_SIZE f_pGetSize ) +{ + tOCT6100_API_INSTANCE_SIZES InstanceSizes; + UINT32 ulResult; + + /* Check user configuration for errors and conflicts. */ + ulResult = Oct6100ApiCheckChipConfiguration( f_pChipOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Calculate the instance size required for user's configuration. */ + ulResult = Oct6100ApiCalculateInstanceSizes( f_pChipOpen, &InstanceSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Return required size to user. */ + f_pGetSize->ulApiInstanceSize = InstanceSizes.ulApiInstTotal; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChipOpenDef + +Description: Inserts default chip configuration parameters into the + structure pointed to by f_pChipOpen. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pChipOpen Structure containing user chip configuration. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChipOpenDef +UINT32 Oct6100ChipOpenDef( + tPOCT6100_CHIP_OPEN f_pChipOpen ) +{ + UINT32 i; + + f_pChipOpen->ulUserChipId = 0; + f_pChipOpen->fMultiProcessSystem = FALSE; + f_pChipOpen->pProcessContext = NULL; + + f_pChipOpen->ulMaxRwAccesses = 8; + + f_pChipOpen->pbyImageFile = NULL; + f_pChipOpen->ulImageSize = 0; + + f_pChipOpen->ulMemClkFreq = 133000000; /* 133 Mhz */ + f_pChipOpen->ulUpclkFreq = cOCT6100_UPCLK_FREQ_33_33_MHZ; /* 33.33 Mhz */ + f_pChipOpen->fEnableMemClkOut = TRUE; + + f_pChipOpen->ulMemoryType = cOCT6100_MEM_TYPE_DDR; + f_pChipOpen->ulNumMemoryChips = 1; + f_pChipOpen->ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_64MB; + + /* Set the tail displacement to zero. */ + f_pChipOpen->ulTailDisplacement = 0; + + /* Disable acoustic echo by default. */ + f_pChipOpen->fEnableAcousticEcho = FALSE; + + /* Resource allocation parameters. */ + f_pChipOpen->ulMaxChannels = 256; + f_pChipOpen->ulMaxTsiCncts = 0; + f_pChipOpen->ulMaxBiDirChannels = 0; + f_pChipOpen->ulMaxConfBridges = 0; + f_pChipOpen->ulMaxFlexibleConfParticipants = 0; + f_pChipOpen->ulMaxPlayoutBuffers = 0; + + f_pChipOpen->ulMaxPhasingTssts = 0; + f_pChipOpen->ulMaxAdpcmChannels = 0; + f_pChipOpen->ulMaxTdmStreams = 32; + f_pChipOpen->fUseSynchTimestamp = FALSE; + for ( i = 0; i < 4; i++ ) + { + f_pChipOpen->aulTimestampTimeslots[ i ] = cOCT6100_INVALID_TIMESLOT; + f_pChipOpen->aulTimestampStreams[ i ] = cOCT6100_INVALID_STREAM; + } + f_pChipOpen->fEnableFastH100Mode = FALSE; + + /* Configure the soft tone event buffer. */ + f_pChipOpen->ulSoftToneEventsBufSize = 128; + f_pChipOpen->fEnableExtToneDetection = FALSE; + f_pChipOpen->fEnable2100StopEvent = FALSE; + + /* Configure the soft playout event buffer. */ + f_pChipOpen->ulSoftBufferPlayoutEventsBufSize = cOCT6100_INVALID_VALUE; + + /* Interrupt configuration. */ + f_pChipOpen->ulInterruptPolarity = cOCT6100_ACTIVE_LOW_POLARITY; + + f_pChipOpen->InterruptConfig.ulErrorMemoryConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pChipOpen->InterruptConfig.ulFatalGeneralConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pChipOpen->InterruptConfig.ulFatalMemoryConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pChipOpen->InterruptConfig.ulFatalMemoryConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pChipOpen->InterruptConfig.ulErrorH100Config = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + + f_pChipOpen->InterruptConfig.ulErrorMemoryTimeout = 100; + f_pChipOpen->InterruptConfig.ulFatalMemoryTimeout = 100; + f_pChipOpen->InterruptConfig.ulErrorH100Timeout = 100; + f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsTimeout = 100; + f_pChipOpen->ulMaxRemoteDebugSessions = 0; + f_pChipOpen->ulTdmSampling = cOCT6100_TDM_SAMPLE_AT_3_QUARTERS; + for ( i = 0; i < cOCT6100_TDM_STREAM_MAX_GROUPS; i++ ) + f_pChipOpen->aulTdmStreamFreqs[ i ] = cOCT6100_TDM_STREAM_FREQ_8MHZ; + + + + f_pChipOpen->fEnableChannelRecording = FALSE; + f_pChipOpen->fEnableProductionBist = FALSE; + f_pChipOpen->ulProductionBistMode = cOCT6100_PRODUCTION_BIST_STANDARD; + f_pChipOpen->ulNumProductionBistLoops = 1; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChipOpen + +Description: Configures the chip according to the user specified + configuration f_pChipOpen. This function will perform all I/O + accesses necessary and initialize the API instance to reflect + the configuration. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChipOpen Structure containing user chip configuration. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChipOpen +UINT32 Oct6100ChipOpen( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CHIP_OPEN f_pChipOpen ) +{ + tOCT6100_API_INSTANCE_SIZES *InstanceSizes; + UINT32 ulStructSize; + UINT32 ulResult; + UINT32 ulTempVar; + + /* Check user chip configuration parameters for errors. */ + ulResult = Oct6100ApiCheckChipConfiguration( f_pChipOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the host system is multi-process or not and adjust instance accordingly. */ + if ( f_pChipOpen->fMultiProcessSystem != TRUE ) + { + /* Set pointer to tOCT6100_SHARED_INFO structure within instance. */ + ulStructSize = sizeof( tOCT6100_INSTANCE_API ); + mOCT6100_ROUND_MEMORY_SIZE( ulStructSize, ulTempVar ) + + f_pApiInstance->pSharedInfo = ( tPOCT6100_SHARED_INFO )(( PUINT8 )f_pApiInstance + ulStructSize); + + /* Save the process context specified by the user. */ + f_pApiInstance->pProcessContext = f_pChipOpen->pProcessContext; + + /* Create serialization object handles. */ + ulResult = Oct6100ApiCreateSerializeObjects( f_pApiInstance, f_pChipOpen->ulUserChipId ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Copy the configuration structure. */ + ulResult = Oct6100ApiCopyChipConfiguration( f_pApiInstance, f_pChipOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Perform various calculations based on user chip configuration. */ + ulResult = Oct6100ApiInitializeMiscellaneousVariables( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + InstanceSizes = kmalloc(sizeof(tOCT6100_API_INSTANCE_SIZES), GFP_ATOMIC); + if (!InstanceSizes) + return cOCT6100_ERR_FATAL_0; + + /* Calculate the amount of memory needed for the API instance structure. */ + ulResult = Oct6100ApiCalculateInstanceSizes( f_pChipOpen, InstanceSizes ); + if ( ulResult != cOCT6100_ERR_OK ) { + kfree(InstanceSizes); + return ulResult; + } + + /* Allocate the memory for the API instance structure internal pointers. */ + ulResult = Oct6100ApiAllocateInstanceMemory( f_pApiInstance, InstanceSizes ); + kfree(InstanceSizes); + + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize the allocated instance structure memory. */ + ulResult = Oct6100ApiInitializeInstanceMemory( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize the tone information structure. */ + ulResult = Oct6100ApiInitToneInfo( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Test the CPU registers. */ + ulResult = Oct6100ApiCpuRegisterBist( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Boot the FC2 PLL. */ + ulResult = Oct6100ApiBootFc2Pll( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Program the FC1 PLL. */ + ulResult = Oct6100ApiProgramFc1Pll( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Decode the key and bist internal memories. */ + ulResult = Oct6100ApiDecodeKeyAndBist( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Boot the FC1 PLL. */ + ulResult = Oct6100ApiBootFc1Pll( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Boot the SDRAM. */ + ulResult = Oct6100ApiBootSdram( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Bist the external memory. */ + ulResult = Oct6100ApiExternalMemoryBist( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize the external memory. */ + ulResult = Oct6100ApiExternalMemoryInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Load the image into the chip. */ + ulResult = Oct6100ApiLoadImage( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write the clock distribution registers. */ + ulResult = Oct6100ApiEnableClocks( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Program the NLP processor. */ + ulResult = Oct6100ApiProgramNLP( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_OPEN_EGO_TIMEOUT ) + ulResult = Oct6100ApiProgramNLP( f_pApiInstance ); + } + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( f_pChipOpen->fEnableProductionBist == FALSE ) + { + /* Read all TLV fields present in external memory. */ + ulResult = Oct6100ApiProcessTlvRegion( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the H.100 interface. */ + ulResult = Oct6100ApiSetH100Register( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Write miscellaneous registers. */ + ulResult = Oct6100ApiWriteMiscellaneousRegisters( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Proceed with the rest only if the production BIST has not been requested. */ + if ( f_pChipOpen->fEnableProductionBist == FALSE ) + { + /* Initialize the errors counters. */ + ulResult = Oct6100ApiChipStatsSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Get revision number of chip. */ + ulResult = Oct6100ApiGetChipRevisionNum( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + + + + /* Initialize the channels. */ + ulResult = Oct6100ApiInitChannels( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize the mixer memory. */ + ulResult = Oct6100ApiInitMixer( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize the mixer memory. */ + ulResult = Oct6100ApiInitRecordResources( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize free external memory for buffer playout. */ + ulResult = Oct6100ApiBufferPlayoutMemorySwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + + + /*Clear all interrupts that could have occured during startup*/ + ulResult = Oct6100ApiClearInterrupts( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the interrupt registers. */ + ulResult = Oct6100ApiIsrHwInit( f_pApiInstance, &f_pChipOpen->InterruptConfig ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChipCloseDef + +Description: Puts the chip into soft reset. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChipClose Pointer to a tOCT6100_CHIP_CLOSE structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChipCloseDef +UINT32 Oct6100ChipCloseDef( + tPOCT6100_CHIP_CLOSE f_pChipClose ) +{ + f_pChipClose->ulDummyVariable = 0; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChipClose +UINT32 Oct6100ChipClose( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CHIP_CLOSE f_pChipClose ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + WriteParams.ulWriteAddress = 0x100; + WriteParams.usWriteData = 0x0000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Destroy the allocated ressources used for serialization. */ + ulResult = Oct6100ApiDestroySerializeObjects( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100CreateLocalInstance + +Description: Creates a local instance for a process in a multi-process + host system. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pCreateLocal Structure used to create process' local instance. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100CreateLocalInstanceDef +UINT32 Oct6100CreateLocalInstanceDef( + tPOCT6100_CREATE_LOCAL_INSTANCE f_pCreateLocal ) +{ + f_pCreateLocal->pApiInstShared = NULL; + f_pCreateLocal->pApiInstLocal = NULL; + f_pCreateLocal->pProcessContext = NULL; + f_pCreateLocal->ulUserChipId = 0; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100CreateLocalInstance +UINT32 Oct6100CreateLocalInstance( + tPOCT6100_CREATE_LOCAL_INSTANCE f_pCreateLocal ) +{ + tPOCT6100_INSTANCE_API pApiInstLocal; + UINT32 ulApiInstSize; + UINT32 ulTempVar; + UINT32 ulResult; + + /* Check user's structure for errors. */ + if ( f_pCreateLocal->pApiInstShared == NULL ) + return cOCT6100_ERR_MULTIPROC_API_INST_SHARED; + + if ( f_pCreateLocal->pApiInstLocal == NULL ) + return cOCT6100_ERR_MULTIPROC_API_INST_LOCAL; + + /* Get local pointer to local instance. */ + pApiInstLocal = f_pCreateLocal->pApiInstLocal; + + /* Assign pointers to local structure. */ + ulApiInstSize = sizeof( tOCT6100_INSTANCE_API ); + mOCT6100_ROUND_MEMORY_SIZE( ulApiInstSize, ulTempVar ) + + pApiInstLocal->pSharedInfo = ( tPOCT6100_SHARED_INFO )(( PUINT8 )f_pCreateLocal->pApiInstShared + ulApiInstSize); + pApiInstLocal->pProcessContext = f_pCreateLocal->pProcessContext; + + /* Create serialization object handles needed. */ + ulResult = Oct6100ApiCreateSerializeObjects( pApiInstLocal, f_pCreateLocal->ulUserChipId ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100DestroyLocalInstance + +Description: Release local instance for a process in a multi-process + host system. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pDestroyLocal Structure used to destroy the process' local instance. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100DestroyLocalInstanceDef +UINT32 Oct6100DestroyLocalInstanceDef( + tPOCT6100_DESTROY_LOCAL_INSTANCE f_pDestroyLocal ) +{ + f_pDestroyLocal->ulDummy = 0; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100DestroyLocalInstance +UINT32 Oct6100DestroyLocalInstance( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_DESTROY_LOCAL_INSTANCE f_pDestroyLocal ) +{ + UINT32 ulResult; + + /* Destroy the allocated ressources used for serialization. */ + ulResult = Oct6100ApiDestroySerializeObjects( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100GetHwRevision + +Description: Gets the hardware revision number of the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pGetHwRev Pointer to user structure in which to return revision + number. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100GetHwRevisionDef +UINT32 Oct6100GetHwRevisionDef( + tPOCT6100_GET_HW_REVISION f_pGetHwRev ) +{ + f_pGetHwRev->ulUserChipId = cOCT6100_INVALID_CHIP_ID; + f_pGetHwRev->pProcessContext = NULL; + f_pGetHwRev->ulRevisionNum = cOCT6100_INVALID_VALUE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100GetHwRevision +UINT32 Oct6100GetHwRevision( + tPOCT6100_GET_HW_REVISION f_pGetHwRev ) +{ + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT16 usReadData; + + /* Read the hardware revision register. */ + ReadParams.pProcessContext = f_pGetHwRev->pProcessContext; + + ReadParams.ulUserChipId = f_pGetHwRev->ulUserChipId; + ReadParams.pusReadData = &usReadData; + ReadParams.ulReadAddress = 0x17E; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + f_pGetHwRev->ulRevisionNum = ( usReadData >> 8 ) & 0xFF; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100FreeResources + +Description: This function closes all opened channels and frees all + specified global resources used by the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pFreeResources Pointer to user structure in which to choose what + to free. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100FreeResourcesDef +UINT32 Oct6100FreeResourcesDef( + tPOCT6100_FREE_RESOURCES f_pFreeResources ) +{ + f_pFreeResources->fFreeTsiConnections = FALSE; + f_pFreeResources->fFreeConferenceBridges = FALSE; + f_pFreeResources->fFreePlayoutBuffers = FALSE; + f_pFreeResources->fFreePhasingTssts = FALSE; + f_pFreeResources->fFreeAdpcmChannels = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100FreeResources +UINT32 Oct6100FreeResources( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_FREE_RESOURCES f_pFreeResources ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100FreeResourcesSer( f_pApiInstance, f_pFreeResources ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ProductionBist + +Description: This function retrieves the current BIST status of the + firmware. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pProductionBist Pointer to user structure where the bist information + will be returned. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ProductionBistDef +UINT32 Oct6100ProductionBistDef( + tPOCT6100_PRODUCTION_BIST f_pProductionBist ) +{ + f_pProductionBist->ulCurrentAddress = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulCurrentLoop = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulFailedAddress = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulReadValue = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulExpectedValue = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulBistStatus = cOCT6100_BIST_IN_PROGRESS; + f_pProductionBist->ulCurrentTest = cOCT6100_INVALID_VALUE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ProductionBist +UINT32 Oct6100ProductionBist( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_PRODUCTION_BIST f_pProductionBist ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ProductionBistSer( f_pApiInstance, f_pProductionBist ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetVersion + +Description: Retrieves the API version. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pApiGetVersion Pointer to structure that will receive version information. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetVersionDef +UINT32 Oct6100ApiGetVersionDef( + tPOCT6100_API_GET_VERSION f_pApiGetVersion ) +{ + UINT32 i; + + /* Initialize the string. */ + for ( i = 0; i < cOCT6100_API_VERSION_STRING_LENGTH; i++ ) + f_pApiGetVersion->achApiVersion[ i ] = 0; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ApiGetVersion +UINT32 Oct6100ApiGetVersion( + tPOCT6100_API_GET_VERSION f_pApiGetVersion ) +{ + /* Copy API version information to user. */ + Oct6100UserMemCopy( f_pApiGetVersion->achApiVersion, cOCT6100_API_VERSION, sizeof(cOCT6100_API_VERSION) ); + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetCapacityPins + +Description: Retrieves the Capcity Pins value. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pGetCapacityPins Pointer to the parameters structure needed + by GetCapacityPins(). + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetCapacityPinsDef +UINT32 Oct6100ApiGetCapacityPinsDef( + tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins) +{ + + f_pGetCapacityPins->pProcessContext = NULL; + f_pGetCapacityPins->ulUserChipId = 0; + f_pGetCapacityPins->ulMemoryType = cOCT6100_MEM_TYPE_DDR; + f_pGetCapacityPins->ulCapacityValue = cOCT6100_INVALID_VALUE; + f_pGetCapacityPins->fEnableMemClkOut = TRUE; + f_pGetCapacityPins->ulMemClkFreq = 133000000; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ApiGetCapacityPins +UINT32 Oct6100ApiGetCapacityPins( + tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins ) +{ + + UINT32 ulResult; + + tOCT6100_INSTANCE_API ApiInstance; + + Oct6100UserMemSet(&ApiInstance,0,sizeof(tOCT6100_INSTANCE_API)); + + /*Check parameters*/ + if ( f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_133_MHZ && + f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_125_MHZ && + f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_117_MHZ && + f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_108_MHZ && + f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_100_MHZ && + f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_92_MHZ && + f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_83_MHZ && + f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_75_MHZ ) + return cOCT6100_ERR_OPEN_MEM_CLK_FREQ; + + if ( f_pGetCapacityPins->fEnableMemClkOut != TRUE && + f_pGetCapacityPins->fEnableMemClkOut != FALSE ) + return cOCT6100_ERR_OPEN_ENABLE_MEM_CLK_OUT; + + if ( f_pGetCapacityPins->ulMemoryType != cOCT6100_MEM_TYPE_SDR && + f_pGetCapacityPins->ulMemoryType != cOCT6100_MEM_TYPE_DDR && + f_pGetCapacityPins->ulMemoryType != cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + return cOCT6100_ERR_OPEN_MEMORY_TYPE; + + + + ApiInstance.pProcessContext = f_pGetCapacityPins->pProcessContext; + + + + ulResult = Oct6100ApiReadCapacity(&ApiInstance, f_pGetCapacityPins); + + + + return ulResult; +} +#endif + +/*************************** PRIVATE FUNCTIONS *****************************/ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReadCapacity + +Description: Read the capacity pins using modified functions from the openchip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pChipOpen Pointer to chip configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OCT6100ApiReadCapacity +UINT32 Oct6100ApiReadCapacity( IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins) +{ + UINT32 ulResult; + tOCT6100_READ_PARAMS ReadParams; + UINT16 usReadData; + + /*Read capacity Pins*/ + + + ReadParams.pProcessContext = f_pGetCapacityPins->pProcessContext; + ReadParams.ulUserChipId = f_pGetCapacityPins->ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /*Check the Reset register*/ + ReadParams.ulReadAddress = 0x100; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ((usReadData & 0xFFFF) != 0x0000) + return cOCT6100_ERR_CAP_PINS_INVALID_CHIP_STATE; + + /* Test the CPU registers. */ + ulResult = Oct6100ApiCpuRegisterBistReadCap( f_pApiInstance, f_pGetCapacityPins ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Boot the FC2 PLL. */ + ulResult = Oct6100ApiBootFc2PllReadCap( f_pApiInstance,f_pGetCapacityPins ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Program the FC1 PLL. */ + ulResult = Oct6100ApiProgramFc1PllReadCap( f_pApiInstance,f_pGetCapacityPins ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( (f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR) || + (f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS) ) + { + ReadParams.ulReadAddress = 0x168; + } + else + ReadParams.ulReadAddress = 0x166; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + switch (usReadData & 0xF) + { + case 0x9: + f_pGetCapacityPins->ulCapacityValue = 16; + break; + case 0x8: + f_pGetCapacityPins->ulCapacityValue = 32; + break; + case 0xE: + f_pGetCapacityPins->ulCapacityValue = 64; + break; + case 0x0: + f_pGetCapacityPins->ulCapacityValue = 128; + break; + case 0x2: + f_pGetCapacityPins->ulCapacityValue = 256; + break; + case 0x5: + f_pGetCapacityPins->ulCapacityValue = 512; + break; + case 0x6: + f_pGetCapacityPins->ulCapacityValue = 672; + break; + default: + f_pGetCapacityPins->ulCapacityValue = (usReadData & 0xF); + return cOCT6100_ERR_CAP_PINS_INVALID_CAPACITY_VALUE; + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckChipConfiguration + +Description: Checks the user chip configuration structure for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pChipOpen Pointer to chip configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckChipConfiguration +UINT32 Oct6100ApiCheckChipConfiguration( + IN tPOCT6100_CHIP_OPEN f_pChipOpen ) +{ + UINT32 ulTempVar; + UINT32 i; + + /*-----------------------------------------------------------------------------*/ + /* Check general parameters. */ + if ( f_pChipOpen->fMultiProcessSystem != TRUE && + f_pChipOpen->fMultiProcessSystem != FALSE ) + return cOCT6100_ERR_OPEN_MULTI_PROCESS_SYSTEM; + + if ( f_pChipOpen->ulMaxRwAccesses < 1 || + f_pChipOpen->ulMaxRwAccesses > 1024) + return cOCT6100_ERR_OPEN_MAX_RW_ACCESSES; + + /* Check the clocks. */ + if ( f_pChipOpen->ulUpclkFreq != cOCT6100_UPCLK_FREQ_33_33_MHZ ) + return cOCT6100_ERR_OPEN_UP_CLK_FREQ; + + if ( f_pChipOpen->ulMemClkFreq != cOCT6100_MCLK_FREQ_133_MHZ ) + return cOCT6100_ERR_OPEN_MEM_CLK_FREQ; + + if ( f_pChipOpen->fEnableMemClkOut != TRUE && + f_pChipOpen->fEnableMemClkOut != FALSE ) + return cOCT6100_ERR_OPEN_ENABLE_MEM_CLK_OUT; + + /* Check the image file. */ + if ( f_pChipOpen->ulImageSize < cOCT6100_MIN_IMAGE_SIZE || + f_pChipOpen->ulImageSize > cOCT6100_MAX_IMAGE_SIZE ) + return cOCT6100_ERR_OPEN_IMAGE_SIZE; + + if ( f_pChipOpen->pbyImageFile == NULL ) + return cOCT6100_ERR_OPEN_IMAGE_FILE; + + ulTempVar = Oct6100ApiCheckImageFileHeader(f_pChipOpen); + if (ulTempVar != cOCT6100_ERR_OK) + return ulTempVar; + + /* Check the acoustic echo activation flag. */ + if ( f_pChipOpen->fEnableAcousticEcho != TRUE && + f_pChipOpen->fEnableAcousticEcho != FALSE ) + return cOCT6100_ERR_OPEN_ENABLE_ACOUSTIC_ECHO; + + /* Check the tail displacement parameter. */ + if ( f_pChipOpen->ulTailDisplacement > cOCT6100_MAX_TAIL_DISPLACEMENT ) + return cOCT6100_ERR_OPEN_TAIL_DISPLACEMENT; + + /*-----------------------------------------------------------------------------*/ + /* Check TDM bus configuration parameters. */ + for ( i = 0; i < 8; i++ ) + { + if ( f_pChipOpen->aulTdmStreamFreqs[ i ] != cOCT6100_TDM_STREAM_FREQ_2MHZ && + f_pChipOpen->aulTdmStreamFreqs[ i ] != cOCT6100_TDM_STREAM_FREQ_4MHZ && + f_pChipOpen->aulTdmStreamFreqs[ i ] != cOCT6100_TDM_STREAM_FREQ_8MHZ) + return cOCT6100_ERR_OPEN_TDM_STREAM_FREQS; + } + + if ( f_pChipOpen->ulTdmSampling != cOCT6100_TDM_SAMPLE_AT_3_QUARTERS && + f_pChipOpen->ulTdmSampling != cOCT6100_TDM_SAMPLE_AT_RISING_EDGE && + f_pChipOpen->ulTdmSampling != cOCT6100_TDM_SAMPLE_AT_FALLING_EDGE ) + return cOCT6100_ERR_OPEN_TDM_SAMPLING; + + if ( f_pChipOpen->fEnableFastH100Mode != TRUE && + f_pChipOpen->fEnableFastH100Mode != FALSE ) + return cOCT6100_ERR_OPEN_FAST_H100_MODE; + + /*-----------------------------------------------------------------------------*/ + /* Check external memory configuration parameters. */ + if ( f_pChipOpen->ulMemoryType != cOCT6100_MEM_TYPE_SDR && + f_pChipOpen->ulMemoryType != cOCT6100_MEM_TYPE_DDR && + f_pChipOpen->ulMemoryType != cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + return cOCT6100_ERR_OPEN_MEMORY_TYPE; + + if ( f_pChipOpen->ulMemoryChipSize != cOCT6100_MEMORY_CHIP_SIZE_8MB && + f_pChipOpen->ulMemoryChipSize != cOCT6100_MEMORY_CHIP_SIZE_16MB && + f_pChipOpen->ulMemoryChipSize != cOCT6100_MEMORY_CHIP_SIZE_32MB && + f_pChipOpen->ulMemoryChipSize != cOCT6100_MEMORY_CHIP_SIZE_64MB && + f_pChipOpen->ulMemoryChipSize != cOCT6100_MEMORY_CHIP_SIZE_128MB ) + return cOCT6100_ERR_OPEN_MEMORY_CHIP_SIZE; + + if ( f_pChipOpen->ulMemoryChipSize == cOCT6100_MEMORY_CHIP_SIZE_8MB && + f_pChipOpen->ulMemoryType == cOCT6100_MEM_TYPE_DDR ) + return cOCT6100_ERR_OPEN_MEMORY_CHIP_SIZE; + + if ( f_pChipOpen->ulNumMemoryChips < 1 || + f_pChipOpen->ulNumMemoryChips > cOCT6100_MAX_NUM_MEMORY_CHIP ) + return cOCT6100_ERR_OPEN_MEMORY_CHIPS_NUMBER; + + /* Check the total memory size. */ + ulTempVar = f_pChipOpen->ulMemoryChipSize * f_pChipOpen->ulNumMemoryChips; + if ( ulTempVar < cOCT6100_MEMORY_CHIP_SIZE_16MB || + ulTempVar > cOCT6100_MEMORY_CHIP_SIZE_128MB ) + return cOCT6100_ERR_OPEN_TOTAL_MEMORY_SIZE; + + if ( f_pChipOpen->ulMaxTdmStreams != 4 && + f_pChipOpen->ulMaxTdmStreams != 8 && + f_pChipOpen->ulMaxTdmStreams != 16 && + f_pChipOpen->ulMaxTdmStreams != 32 ) + return cOCT6100_ERR_OPEN_MAX_TDM_STREAM; + + if ( f_pChipOpen->ulMaxTdmStreams > 8 && + f_pChipOpen->ulMemClkFreq == cOCT6100_MCLK_FREQ_75_MHZ ) + return cOCT6100_ERR_OPEN_MAX_TDM_STREAM; + + if ( f_pChipOpen->fUseSynchTimestamp != TRUE && + f_pChipOpen->fUseSynchTimestamp != FALSE ) + return cOCT6100_ERR_OPEN_USE_SYNCH_TIMESTAMP; + + if ( f_pChipOpen->fUseSynchTimestamp == TRUE ) + { + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_USE_SYNCH_TIMESTAMP; + } + + /*-----------------------------------------------------------------------------*/ + /* Check soft buffer for tone events size. */ + if (f_pChipOpen->ulSoftToneEventsBufSize < 64 || + f_pChipOpen->ulSoftToneEventsBufSize > cOCT6100_ABSOLUTE_MAX_NUM_PGSP_EVENT_OUT ) + return cOCT6100_ERR_OPEN_SOFT_TONE_EVENT_SIZE; + + if ( f_pChipOpen->fEnableExtToneDetection != TRUE && + f_pChipOpen->fEnableExtToneDetection != FALSE ) + return cOCT6100_ERR_OPEN_ENABLE_EXT_TONE_DETECTION; + + if ( f_pChipOpen->fEnable2100StopEvent != TRUE && + f_pChipOpen->fEnable2100StopEvent != FALSE) + return cOCT6100_ERR_OPEN_ENABLE_2100_STOP_EVENT; + + /* Check soft buffer for playout events size. */ + if ( ( f_pChipOpen->ulSoftBufferPlayoutEventsBufSize != cOCT6100_INVALID_VALUE ) + && ( f_pChipOpen->ulSoftBufferPlayoutEventsBufSize < cOCT6100_MIN_BUFFER_PLAYOUT_EVENT || + f_pChipOpen->ulSoftBufferPlayoutEventsBufSize > cOCT6100_MAX_BUFFER_PLAYOUT_EVENT ) ) + return cOCT6100_ERR_OPEN_SOFT_PLAYOUT_STOP_EVENT_SIZE; + + /*-----------------------------------------------------------------------------*/ + /* Check interrupt configuration parameters. */ + if ( f_pChipOpen->ulInterruptPolarity != cOCT6100_ACTIVE_LOW_POLARITY && + f_pChipOpen->ulInterruptPolarity != cOCT6100_ACTIVE_HIGH_POLARITY ) + return cOCT6100_ERR_OPEN_INTERRUPT_POLARITY; + + if ( f_pChipOpen->InterruptConfig.ulFatalGeneralConfig != cOCT6100_INTERRUPT_NO_TIMEOUT && + f_pChipOpen->InterruptConfig.ulFatalGeneralConfig != cOCT6100_INTERRUPT_DISABLE ) + return cOCT6100_ERR_OPEN_FATAL_GENERAL_CONFIG; + + if ( f_pChipOpen->InterruptConfig.ulFatalMemoryConfig != cOCT6100_INTERRUPT_NO_TIMEOUT && + f_pChipOpen->InterruptConfig.ulFatalMemoryConfig != cOCT6100_INTERRUPT_TIMEOUT && + f_pChipOpen->InterruptConfig.ulFatalMemoryConfig != cOCT6100_INTERRUPT_DISABLE ) + return cOCT6100_ERR_OPEN_FATAL_MEMORY_CONFIG; + + if ( f_pChipOpen->InterruptConfig.ulErrorMemoryConfig != cOCT6100_INTERRUPT_NO_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorMemoryConfig != cOCT6100_INTERRUPT_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorMemoryConfig != cOCT6100_INTERRUPT_DISABLE ) + return cOCT6100_ERR_OPEN_ERROR_MEMORY_CONFIG; + + if ( f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsConfig != cOCT6100_INTERRUPT_NO_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsConfig != cOCT6100_INTERRUPT_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsConfig != cOCT6100_INTERRUPT_DISABLE ) + return cOCT6100_ERR_OPEN_ERROR_OVERFLOW_TONE_EVENTS_CONFIG; + + if ( f_pChipOpen->InterruptConfig.ulErrorH100Config != cOCT6100_INTERRUPT_NO_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorH100Config != cOCT6100_INTERRUPT_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorH100Config != cOCT6100_INTERRUPT_DISABLE ) + return cOCT6100_ERR_OPEN_ERROR_H100_CONFIG; + + /* Check the timeout value. */ + if ( f_pChipOpen->InterruptConfig.ulFatalMemoryTimeout < 10 || + f_pChipOpen->InterruptConfig.ulFatalMemoryTimeout > 10000 ) + return cOCT6100_ERR_OPEN_FATAL_MEMORY_TIMEOUT; + + if ( f_pChipOpen->InterruptConfig.ulErrorMemoryTimeout < 10 || + f_pChipOpen->InterruptConfig.ulErrorMemoryTimeout > 10000 ) + return cOCT6100_ERR_OPEN_ERROR_MEMORY_TIMEOUT; + + if ( f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsTimeout < 10 || + f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsTimeout > 10000 ) + return cOCT6100_ERR_OPEN_ERROR_OVERFLOW_TONE_EVENTS_TIMEOUT; + + if ( f_pChipOpen->InterruptConfig.ulErrorH100Timeout < 10 || + f_pChipOpen->InterruptConfig.ulErrorH100Timeout > 10000 ) + return cOCT6100_ERR_OPEN_ERROR_H100_TIMEOUT; + + /*-----------------------------------------------------------------------------*/ + /* Check maximum resources. */ + + switch ( f_pChipOpen->ulMemClkFreq ) + { + case 133000000: + ulTempVar = 672; + break; + case 125000000: + ulTempVar = 624; + break; + case 117000000: + ulTempVar = 576; + break; + case 108000000: + ulTempVar = 528; + break; + case 100000000: + ulTempVar = 480; + break; + case 92000000: + ulTempVar = 432; + break; + case 83000000: + ulTempVar = 384; + break; + case 75000000: + ulTempVar = 336; + break; + default: + return cOCT6100_ERR_FATAL_DA; + } + + if ( f_pChipOpen->ulMaxChannels > ulTempVar ) + return cOCT6100_ERR_OPEN_MAX_ECHO_CHANNELS; + + if ( f_pChipOpen->ulMaxTsiCncts > cOCT6100_MAX_TSI_CNCTS ) + return cOCT6100_ERR_OPEN_MAX_TSI_CNCTS; + + + if ( f_pChipOpen->ulMaxBiDirChannels > 255 ) + return cOCT6100_ERR_OPEN_MAX_BIDIR_CHANNELS; + + if ( f_pChipOpen->ulMaxBiDirChannels > (f_pChipOpen->ulMaxChannels / 2) ) + return cOCT6100_ERR_OPEN_MAX_BIDIR_CHANNELS; + + if ( f_pChipOpen->ulMaxConfBridges > cOCT6100_MAX_CONF_BRIDGE ) + return cOCT6100_ERR_OPEN_MAX_CONF_BRIDGES; + + if ( f_pChipOpen->ulMaxFlexibleConfParticipants > cOCT6100_MAX_FLEX_CONF_PARTICIPANTS ) + return cOCT6100_ERR_OPEN_MAX_FLEXIBLE_CONF_PARTICIPANTS; + + if ( f_pChipOpen->ulMaxPlayoutBuffers > cOCT6100_MAX_PLAYOUT_BUFFERS ) + return cOCT6100_ERR_OPEN_MAX_PLAYOUT_BUFFERS; + + + + if ( f_pChipOpen->ulMaxPhasingTssts > cOCT6100_MAX_PHASING_TSST ) + return cOCT6100_ERR_OPEN_MAX_PHASING_TSSTS; + + if ( f_pChipOpen->ulMaxAdpcmChannels > cOCT6100_MAX_ADPCM_CHANNELS ) + return cOCT6100_ERR_OPEN_MAX_ADPCM_CHANNELS; + + if ( f_pChipOpen->ulMaxRemoteDebugSessions > 256 ) + return cOCT6100_ERR_OPEN_MAX_REMOTE_DEBUG_SESSIONS; + + + + + + /* Check the channel recording flag. */ + if ( f_pChipOpen->fEnableChannelRecording != TRUE && + f_pChipOpen->fEnableChannelRecording != FALSE ) + return cOCT6100_ERR_OPEN_DEBUG_CHANNEL_RECORDING; + + /* Check the enable production BIST flag. */ + if ( ( f_pChipOpen->fEnableProductionBist != TRUE ) + && ( f_pChipOpen->fEnableProductionBist != FALSE ) ) + return cOCT6100_ERR_OPEN_ENABLE_PRODUCTION_BIST; + + /* Check number of loops for the production BIST. */ + if ( f_pChipOpen->fEnableProductionBist == TRUE ) + { + if ( f_pChipOpen->ulNumProductionBistLoops == 0 ) + return cOCT6100_ERR_OPEN_NUM_PRODUCTION_BIST_LOOPS; + + if ( (f_pChipOpen->ulProductionBistMode != cOCT6100_PRODUCTION_BIST_STANDARD) && + (f_pChipOpen->ulProductionBistMode != cOCT6100_PRODUCTION_BIST_SHORT) ) + return cOCT6100_ERR_OPEN_PRODUCTION_BIST_MODE; + } + + /* If the production BIST has been requested, make sure all */ + /* other resources are disabled. */ + if ( f_pChipOpen->fEnableProductionBist == TRUE ) + { + /* All must be disabled. */ + f_pChipOpen->ulMaxChannels = 0; + f_pChipOpen->ulMaxTsiCncts = 0; + f_pChipOpen->fEnableChannelRecording = FALSE; + f_pChipOpen->ulMaxBiDirChannels = 0; + f_pChipOpen->ulMaxConfBridges = 0; + f_pChipOpen->ulMaxPlayoutBuffers = 0; + f_pChipOpen->ulSoftBufferPlayoutEventsBufSize = cOCT6100_INVALID_VALUE; + f_pChipOpen->ulMaxPhasingTssts = 0; + f_pChipOpen->ulMaxAdpcmChannels = 0; + + + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCopyChipConfiguration + +Description: Copies the chip configuration from the user supplied config + structure to the instance structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChipOpen Pointer to chip configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCopyChipConfiguration +UINT32 Oct6100ApiCopyChipConfiguration( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHIP_OPEN f_pChipOpen ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + pSharedInfo->ChipConfig.ulUserChipId = f_pChipOpen->ulUserChipId; + pSharedInfo->ChipConfig.fMultiProcessSystem = (UINT8)( f_pChipOpen->fMultiProcessSystem & 0xFF ); + + pSharedInfo->ChipConfig.usMaxRwAccesses = (UINT16)( f_pChipOpen->ulMaxRwAccesses & 0xFFFF ); + + pSharedInfo->ChipConfig.pbyImageFile = f_pChipOpen->pbyImageFile; + pSharedInfo->ChipConfig.ulImageSize = f_pChipOpen->ulImageSize; + + pSharedInfo->ChipConfig.ulMemClkFreq = f_pChipOpen->ulMemClkFreq; + pSharedInfo->ChipConfig.ulUpclkFreq = f_pChipOpen->ulUpclkFreq; + + pSharedInfo->ChipConfig.byMemoryType = (UINT8)( f_pChipOpen->ulMemoryType & 0xFF ); + pSharedInfo->ChipConfig.byNumMemoryChips = (UINT8)( f_pChipOpen->ulNumMemoryChips & 0xFF ); + pSharedInfo->ChipConfig.ulMemoryChipSize = f_pChipOpen->ulMemoryChipSize; + + pSharedInfo->ChipConfig.usTailDisplacement = (UINT16)( f_pChipOpen->ulTailDisplacement & 0xFFFF ); + pSharedInfo->ChipConfig.fEnableAcousticEcho = (UINT8)( f_pChipOpen->fEnableAcousticEcho & 0xFF ); + /* Resource allocation parameters. */ + if ( f_pChipOpen->fEnableChannelRecording == TRUE && f_pChipOpen->ulMaxChannels == 672 ) + pSharedInfo->ChipConfig.usMaxChannels = (UINT16)( ( f_pChipOpen->ulMaxChannels - 1 ) & 0xFFFF ); + else + pSharedInfo->ChipConfig.usMaxChannels = (UINT16)( f_pChipOpen->ulMaxChannels & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxTsiCncts = (UINT16)( f_pChipOpen->ulMaxTsiCncts & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxBiDirChannels = (UINT16)( f_pChipOpen->ulMaxBiDirChannels & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxConfBridges = (UINT16)( f_pChipOpen->ulMaxConfBridges & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxFlexibleConfParticipants = (UINT16)( f_pChipOpen->ulMaxFlexibleConfParticipants & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxPlayoutBuffers = (UINT16)( f_pChipOpen->ulMaxPlayoutBuffers & 0xFFFF ); + + pSharedInfo->ChipConfig.usMaxPhasingTssts = (UINT16)( f_pChipOpen->ulMaxPhasingTssts & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxAdpcmChannels = (UINT16)( f_pChipOpen->ulMaxAdpcmChannels & 0xFFFF ); + pSharedInfo->ChipConfig.byMaxTdmStreams = (UINT8)( f_pChipOpen->ulMaxTdmStreams & 0xFF ); + pSharedInfo->ChipConfig.fUseSynchTimestamp = (UINT8)( f_pChipOpen->fUseSynchTimestamp & 0xFF ); + for ( i = 0; i < 4; i++ ) + { + pSharedInfo->ChipConfig.ausTimestampTimeslots[ i ] = (UINT16)( f_pChipOpen->aulTimestampTimeslots[ i ] & 0xFFFF ); + pSharedInfo->ChipConfig.ausTimestampStreams[ i ] = (UINT16)( f_pChipOpen->aulTimestampStreams[ i ] & 0xFFFF ); + } + pSharedInfo->ChipConfig.byInterruptPolarity = (UINT8)( f_pChipOpen->ulInterruptPolarity & 0xFF ); + + pSharedInfo->ChipConfig.byTdmSampling = (UINT8)( f_pChipOpen->ulTdmSampling & 0xFF ); + pSharedInfo->ChipConfig.fEnableFastH100Mode = (UINT8)( f_pChipOpen->fEnableFastH100Mode & 0xFF ); + + for ( i = 0; i < cOCT6100_TDM_STREAM_MAX_GROUPS; i++ ) + { + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->ChipConfig.aulTdmStreamFreqs[ i ] = cOCT6100_TDM_STREAM_FREQ_16MHZ; + else + pSharedInfo->ChipConfig.aulTdmStreamFreqs[ i ] = f_pChipOpen->aulTdmStreamFreqs[ i ]; + } + + pSharedInfo->ChipConfig.fEnableFastH100Mode = (UINT8)( f_pChipOpen->fEnableFastH100Mode & 0xFF ); + pSharedInfo->ChipConfig.fEnableMemClkOut = (UINT8)( f_pChipOpen->fEnableMemClkOut & 0xFF ); + + /* Add 1 to the circular buffer such that all user requested events can fit in the circular queue. */ + pSharedInfo->ChipConfig.ulSoftToneEventsBufSize = f_pChipOpen->ulSoftToneEventsBufSize + 1; + pSharedInfo->ChipConfig.fEnableExtToneDetection = (UINT8)( f_pChipOpen->fEnableExtToneDetection & 0xFF ); + pSharedInfo->ChipConfig.fEnable2100StopEvent = (UINT8)( f_pChipOpen->fEnable2100StopEvent & 0xFF ); + + if ( f_pChipOpen->ulSoftBufferPlayoutEventsBufSize != cOCT6100_INVALID_VALUE ) + pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize = f_pChipOpen->ulSoftBufferPlayoutEventsBufSize + 1; + else + pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize = 0; + pSharedInfo->ChipConfig.usMaxRemoteDebugSessions = (UINT16)( f_pChipOpen->ulMaxRemoteDebugSessions & 0xFFFF ); + + pSharedInfo->ChipConfig.fEnableChannelRecording = (UINT8)( f_pChipOpen->fEnableChannelRecording & 0xFF ); + + + + pSharedInfo->ChipConfig.fEnableProductionBist = (UINT8)( f_pChipOpen->fEnableProductionBist & 0xFF ); + pSharedInfo->ChipConfig.ulProductionBistMode = f_pChipOpen->ulProductionBistMode; + pSharedInfo->ChipConfig.ulNumProductionBistLoops = f_pChipOpen->ulNumProductionBistLoops; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitializeMiscellaneousVariables + +Description: Function where all the various parameters from the API instance + are set to their defaults value. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInitializeMiscellaneousVariables +UINT32 Oct6100ApiInitializeMiscellaneousVariables( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 i; + + /* Obtain pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Calculate the total memory available. */ + pSharedInfo->MiscVars.ulTotalMemSize = pSharedInfo->ChipConfig.ulMemoryChipSize * pSharedInfo->ChipConfig.byNumMemoryChips; + + /* Software buffers initialization. */ + + /* Tones */ + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0; + pSharedInfo->SoftBufs.ulToneEventBufferReadPtr = 0; + pSharedInfo->SoftBufs.ulToneEventBufferSize = pSharedInfo->ChipConfig.ulSoftToneEventsBufSize; + pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt = 0; + + /* Playout */ + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr = 0; + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr = 0; + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferSize = pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize; + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt = 0; + + /* Set the number of conference bridges opened to zero. */ + pSharedInfo->MiscVars.usNumBridgesOpened = 0; + pSharedInfo->MiscVars.usFirstBridge = cOCT6100_INVALID_INDEX; + + /* Set the H.100 slave mode. */ + pSharedInfo->MiscVars.ulH100SlaveMode = cOCT6100_H100_TRACKA; + + /* Save the Mclk value.*/ + pSharedInfo->MiscVars.ulMclkFreq = pSharedInfo->ChipConfig.ulMemClkFreq; + + /* Init the NLP params. */ + pSharedInfo->MiscVars.usCodepoint = 0; + pSharedInfo->MiscVars.usCpuLsuWritePtr = 0; + + /* Pouch counter not present until TLVs are read. */ + pSharedInfo->DebugInfo.fPouchCounter = FALSE; + pSharedInfo->DebugInfo.fIsIsrCalledField = FALSE; + + /* Initialize the image info parameters */ + pSharedInfo->ImageInfo.fAdaptiveNoiseReduction = FALSE; + pSharedInfo->ImageInfo.fSoutNoiseBleaching = FALSE; + pSharedInfo->ImageInfo.fComfortNoise = FALSE; + pSharedInfo->ImageInfo.fBufferPlayout = TRUE; + pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip = FALSE; + pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip = FALSE; + pSharedInfo->ImageInfo.fNlpControl = FALSE; + pSharedInfo->ImageInfo.fRinAutoLevelControl = FALSE; + pSharedInfo->ImageInfo.fSoutAutoLevelControl = FALSE; + pSharedInfo->ImageInfo.fRinHighLevelCompensation = FALSE; + pSharedInfo->ImageInfo.fSoutHighLevelCompensation = FALSE; + pSharedInfo->ImageInfo.fAlcHlcStatus = FALSE; + pSharedInfo->ImageInfo.fRinDcOffsetRemoval = FALSE; + pSharedInfo->ImageInfo.fSilenceSuppression = FALSE; + pSharedInfo->ImageInfo.fSinDcOffsetRemoval = FALSE; + pSharedInfo->ImageInfo.fToneDisabler = FALSE; + pSharedInfo->ImageInfo.fAdpcm = FALSE; + pSharedInfo->ImageInfo.fTailDisplacement = FALSE; + pSharedInfo->ImageInfo.fConferencing = FALSE; + pSharedInfo->ImageInfo.fConferencingNoiseReduction = FALSE; + pSharedInfo->ImageInfo.fDominantSpeakerEnabled = FALSE; + pSharedInfo->ImageInfo.fAecEnabled = FALSE; + pSharedInfo->ImageInfo.fAcousticEcho = FALSE; + pSharedInfo->ImageInfo.fToneRemoval = FALSE; + + pSharedInfo->ImageInfo.fDefaultErl = FALSE; + pSharedInfo->ImageInfo.fMaxEchoPoint = FALSE; + pSharedInfo->ImageInfo.fNonLinearityBehaviorA = FALSE; + pSharedInfo->ImageInfo.fNonLinearityBehaviorB = FALSE; + pSharedInfo->ImageInfo.fPerChannelTailDisplacement = FALSE; + pSharedInfo->ImageInfo.fPerChannelTailLength = FALSE; + pSharedInfo->ImageInfo.fAfTailDisplacement = FALSE; + pSharedInfo->ImageInfo.fMusicProtection = FALSE; + pSharedInfo->ImageInfo.fAftControl = FALSE; + pSharedInfo->ImageInfo.fSinVoiceDetectedStat = FALSE; + pSharedInfo->ImageInfo.fRinAppliedGainStat = FALSE; + pSharedInfo->ImageInfo.fSoutAppliedGainStat = FALSE; + pSharedInfo->ImageInfo.fListenerEnhancement = FALSE; + pSharedInfo->ImageInfo.fRoutNoiseReduction = FALSE; + pSharedInfo->ImageInfo.fRoutNoiseReductionLevel = FALSE; + pSharedInfo->ImageInfo.fAnrSnrEnhancement = FALSE; + pSharedInfo->ImageInfo.fAnrVoiceNoiseSegregation = FALSE; + pSharedInfo->ImageInfo.fRinMute = FALSE; + pSharedInfo->ImageInfo.fSinMute = FALSE; + pSharedInfo->ImageInfo.fToneDisablerVqeActivationDelay = FALSE; + pSharedInfo->ImageInfo.fAecTailLength = FALSE; + pSharedInfo->ImageInfo.fMusicProtectionConfiguration= FALSE; + pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents = FALSE; + pSharedInfo->ImageInfo.fRinEnergyStat = FALSE; + pSharedInfo->ImageInfo.fSoutEnergyStat = FALSE; + pSharedInfo->ImageInfo.fDoubleTalkBehavior = FALSE; + pSharedInfo->ImageInfo.fDoubleTalkBehaviorFieldOfst = FALSE; + pSharedInfo->ImageInfo.fIdleCodeDetection = TRUE; + pSharedInfo->ImageInfo.fIdleCodeDetectionConfiguration = FALSE; + pSharedInfo->ImageInfo.fSinLevel = TRUE; + + pSharedInfo->ImageInfo.usMaxNumberOfChannels = 0; + pSharedInfo->ImageInfo.ulToneProfileNumber = cOCT6100_INVALID_VALUE; + pSharedInfo->ImageInfo.ulBuildId = cOCT6100_INVALID_VALUE; + pSharedInfo->ImageInfo.byImageType = cOCT6100_IMAGE_TYPE_WIRELINE; + pSharedInfo->ImageInfo.usMaxTailDisplacement = 0; + pSharedInfo->ImageInfo.usMaxTailLength = cOCT6100_TAIL_LENGTH_128MS; + pSharedInfo->DebugInfo.ulDebugEventSize = 0x100; + pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents = 32; + pSharedInfo->DebugInfo.ulMatrixBaseAddress = cOCT6100_MATRIX_DWORD_BASE; + pSharedInfo->DebugInfo.ulDebugChanStatsByteSize = cOCT6100_DEBUG_CHAN_STATS_EVENT_BYTE_SIZE; + pSharedInfo->DebugInfo.ulDebugChanLiteStatsByteSize = cOCT6100_DEBUG_CHAN_STATS_LITE_EVENT_BYTE_SIZE; + pSharedInfo->DebugInfo.ulHotChannelSelectBaseAddress= cOCT6100_MATRIX_CHAN_SELECT_DWORD_ADD; + pSharedInfo->DebugInfo.ulMatrixTimestampBaseAddress = cOCT6100_MATRIX_TIMESTAMP_DWORD_ADD; + pSharedInfo->DebugInfo.ulMatrixWpBaseAddress = cOCT6100_MATRIX_WRITE_PTR_DWORD_ADD; + pSharedInfo->DebugInfo.ulAfWritePtrByteOffset = 206; + pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize = 4096; + pSharedInfo->DebugInfo.ulAfEventCbByteSize = 0x100000; + + /* Set all tones to invalid. */ + pSharedInfo->ImageInfo.byNumToneDetectors = 0; + for ( i = 0; i < cOCT6100_MAX_TONE_EVENT; i++ ) + { + pSharedInfo->ImageInfo.aToneInfo[ i ].ulToneID = cOCT6100_INVALID_VALUE; + pSharedInfo->ImageInfo.aToneInfo[ i ].ulDetectionPort = cOCT6100_INVALID_PORT; + Oct6100UserMemSet( pSharedInfo->ImageInfo.aToneInfo[ i ].aszToneName, 0x00, cOCT6100_TLV_MAX_TONE_NAME_SIZE ); + } + /* Initialize the channel recording info. */ + pSharedInfo->DebugInfo.usRecordChanIndex = pSharedInfo->ChipConfig.usMaxChannels; + pSharedInfo->DebugInfo.usRecordMemIndex = cOCT6100_INVALID_INDEX; + + pSharedInfo->DebugInfo.usCurrentDebugChanIndex = cOCT6100_INVALID_INDEX; + /* Initialize the mixer information. */ + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usFirstSinCopyEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastBridgeEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastSinCopyEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastSoutCopyEventPtr = cOCT6100_INVALID_INDEX; + + pSharedInfo->MixerInfo.usRecordCopyEventIndex = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usRecordSinEventIndex = cOCT6100_INVALID_INDEX; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCalculateInstanceSizes + +Description: Calculates the amount of memory needed for the instance + structure memory block based on the user's configuration. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pChipOpen Pointer to user chip configuration structure. + +f_pInstSizes Pointer to structure containing the size of memory needed + by all pointers internal to the API instance. The memory + is needed to keep track of the present state of all the + chip's resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCalculateInstanceSizes +UINT32 Oct6100ApiCalculateInstanceSizes( + IN OUT tPOCT6100_CHIP_OPEN f_pChipOpen, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulApiInstProcessSpecific; + UINT32 ulTempVar; + UINT32 ulResult; + + /* Start with all instance sizes set to 0. */ + Oct6100UserMemSet( f_pInstSizes, 0x00, sizeof( tOCT6100_API_INSTANCE_SIZES ) ); + + /* All memory sizes are rounded up to the next multiple of 64 bytes. */ + + /*-----------------------------------------------------------------------------*/ + /* Obtain size of static members of API instance. */ + f_pInstSizes->ulApiInstStatic = sizeof( tOCT6100_SHARED_INFO ); + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulApiInstStatic, ulTempVar ) + + /* Calculate memory needed by pointers internal to the API instance. */ + + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for the EC channels. */ + ulResult = Oct6100ApiGetChannelsEchoSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*-----------------------------------------------------------------------------*/ + /* Memory needed by the TSI structures. */ + ulResult = Oct6100ApiGetTsiCnctSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for the conference bridges. */ + ulResult = Oct6100ApiGetConfBridgeSwSizes( f_pChipOpen, f_pInstSizes ); + /* Calculate memory needed for list and allocation software serialization. */ + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Memory needed by the buffer playout structures. */ + ulResult = Oct6100ApiGetPlayoutBufferSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Memory needed by soft Rx Event buffers. */ + ulResult = Oct6100ApiGetEventsSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for phasing tssts. */ + ulResult = Oct6100ApiGetPhasingTsstSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for the ADPCM channels. */ + ulResult = Oct6100ApiGetAdpcmChanSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for the management of TSSTs. */ + ulResult = Oct6100ApiGetTsstSwSizes( f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for the management of the mixer. */ + ulResult = Oct6100ApiGetMixerSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Determine amount of memory needed for memory allocation softwares. These + pieces of software will be responsible for the allocation of the chip's + external memory and API memory. */ + ulResult = Oct6100ApiGetMemorySwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Memory needed for remote debugging sessions. */ + ulResult = Oct6100ApiGetRemoteDebugSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Calculate total memory needed by pointers internal to API instance. The + total contains both the process specific portion of the instance + (tOCT6100_INSTANCE_API) and the shared portion (tOCT6100_SHARED_INFO). The + process specific portion will be used only in the case where the host system + is a single-process one. */ + + ulApiInstProcessSpecific = sizeof( tOCT6100_INSTANCE_API ); + mOCT6100_ROUND_MEMORY_SIZE( ulApiInstProcessSpecific, ulTempVar ) + f_pInstSizes->ulApiInstTotal = + f_pInstSizes->ulChannelList + + f_pInstSizes->ulChannelAlloc + + f_pInstSizes->ulTsiCnctList + + f_pInstSizes->ulTsiCnctAlloc + + f_pInstSizes->ulSoftToneEventsBuffer + + f_pInstSizes->ulSoftBufPlayoutEventsBuffer + + f_pInstSizes->ulBiDirChannelList + + f_pInstSizes->ulBiDirChannelAlloc + + f_pInstSizes->ulConfBridgeList + + f_pInstSizes->ulConfBridgeAlloc + + f_pInstSizes->ulFlexConfParticipantsList + + f_pInstSizes->ulFlexConfParticipantsAlloc + + f_pInstSizes->ulPlayoutBufList + + f_pInstSizes->ulPlayoutBufAlloc + + f_pInstSizes->ulPlayoutBufMemoryNodeList + + + f_pInstSizes->ulCopyEventList + + f_pInstSizes->ulCopyEventAlloc + + f_pInstSizes->ulMixerEventList + + f_pInstSizes->ulMixerEventAlloc + + f_pInstSizes->ulPhasingTsstList + + f_pInstSizes->ulPhasingTsstAlloc + + f_pInstSizes->ulAdpcmChannelList + + f_pInstSizes->ulAdpcmChannelAlloc + + f_pInstSizes->ulConversionMemoryAlloc + + f_pInstSizes->ulTsiMemoryAlloc + + f_pInstSizes->ulRemoteDebugList + + f_pInstSizes->ulRemoteDebugTree + + f_pInstSizes->ulRemoteDebugPktCache + + f_pInstSizes->ulRemoteDebugDataBuf + + f_pInstSizes->ulTsstEntryList + + f_pInstSizes->ulTsstEntryAlloc + + f_pInstSizes->ulTsstAlloc + + f_pInstSizes->ulApiInstStatic + + ulApiInstProcessSpecific; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAllocateInstanceMemory + +Description: Allocates the API instance memory to the various members of + the structure f_pApiInstance according to the sizes contained + in f_pInstSizes. No initialization of this memory is + performed. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pInstSizes Pointer to structure containing the size of memory needed + by all pointers internal to the API instance. The memory + is needed to keep track of the present state of all the + chip's resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAllocateInstanceMemory +UINT32 Oct6100ApiAllocateInstanceMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulOffset; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get address of first UINT32 of memory in API instance structure following */ + /* the static members of the API instance structure. */ + ulOffset = f_pInstSizes->ulApiInstStatic; + + /*===================================================================*/ + /* Allocate memory for the echo channels.*/ + pSharedInfo->ulChannelListOfst = ulOffset; + ulOffset += f_pInstSizes->ulChannelList; + pSharedInfo->ulChannelAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulChannelAlloc; + + /*===================================================================*/ + /* Allocate memory for the TSI connections */ + pSharedInfo->ulTsiCnctListOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsiCnctList; + pSharedInfo->ulTsiCnctAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsiCnctAlloc; + pSharedInfo->ulMixerEventListOfst = ulOffset; + ulOffset += f_pInstSizes->ulMixerEventList; + pSharedInfo->ulMixerEventAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulMixerEventAlloc; + + pSharedInfo->ulBiDirChannelListOfst = ulOffset; + ulOffset += f_pInstSizes->ulBiDirChannelList; + pSharedInfo->ulBiDirChannelAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulBiDirChannelAlloc; + pSharedInfo->ulCopyEventListOfst = ulOffset; + ulOffset += f_pInstSizes->ulCopyEventList; + pSharedInfo->ulCopyEventAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulCopyEventAlloc; + + /*===================================================================*/ + /* Allocate memory for the conference bridges */ + pSharedInfo->ulConfBridgeListOfst = ulOffset; + ulOffset += f_pInstSizes->ulConfBridgeList; + pSharedInfo->ulConfBridgeAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulConfBridgeAlloc; + + /*===================================================================*/ + /* Allocate memory for the flexible conferencing participants. */ + pSharedInfo->ulFlexConfParticipantListOfst = ulOffset; + ulOffset += f_pInstSizes->ulFlexConfParticipantsList; + pSharedInfo->ulFlexConfParticipantAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulFlexConfParticipantsAlloc; + + /*===================================================================*/ + /* Allocate memory for the play-out buffers */ + pSharedInfo->ulPlayoutBufListOfst = ulOffset; + ulOffset += f_pInstSizes->ulPlayoutBufList; + pSharedInfo->ulPlayoutBufAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulPlayoutBufAlloc; + pSharedInfo->ulPlayoutBufMemoryNodeListOfst = ulOffset; + ulOffset += f_pInstSizes->ulPlayoutBufMemoryNodeList; + + + + /*===================================================================*/ + /* Allocate memory for the phasing TSSTs */ + pSharedInfo->ulPhasingTsstListOfst = ulOffset; + ulOffset += f_pInstSizes->ulPhasingTsstList; + pSharedInfo->ulPhasingTsstAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulPhasingTsstAlloc; + + /*===================================================================*/ + /* Allocate memory for the ADPCM channel */ + pSharedInfo->ulAdpcmChanAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulAdpcmChannelAlloc; + pSharedInfo->ulAdpcmChanListOfst = ulOffset; + ulOffset += f_pInstSizes->ulAdpcmChannelList; + + /*===================================================================*/ + /* Allocate memory for the conversion memory */ + pSharedInfo->ulConversionMemoryAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulConversionMemoryAlloc; + + /*===================================================================*/ + /* Allocate memory for the TSI chariot memory */ + pSharedInfo->ulTsiMemoryAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsiMemoryAlloc; + + /*===================================================================*/ + /* Allocate memory for the TSST management */ + pSharedInfo->ulTsstAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsstAlloc; + pSharedInfo->ulTsstListOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsstEntryList; + pSharedInfo->ulTsstListAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsstEntryAlloc; + + /*===================================================================*/ + pSharedInfo->SoftBufs.ulToneEventBufferMemOfst = ulOffset; + ulOffset += f_pInstSizes->ulSoftToneEventsBuffer; + + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferMemOfst = ulOffset; + ulOffset += f_pInstSizes->ulSoftBufPlayoutEventsBuffer; + /*===================================================================*/ + pSharedInfo->RemoteDebugInfo.ulSessionListOfst = ulOffset; + ulOffset += f_pInstSizes->ulRemoteDebugList; + + pSharedInfo->RemoteDebugInfo.ulSessionTreeOfst = ulOffset; + ulOffset += f_pInstSizes->ulRemoteDebugTree; + + pSharedInfo->RemoteDebugInfo.ulDataBufOfst = ulOffset; + ulOffset += f_pInstSizes->ulRemoteDebugDataBuf; + + pSharedInfo->RemoteDebugInfo.ulPktCacheOfst = ulOffset; + ulOffset += f_pInstSizes->ulRemoteDebugPktCache; + /*===================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitializeInstanceMemory + +Description: Initializes the various members of the structure f_pApiInstance + to reflect the current state of the chip and its resources. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInitializeInstanceMemory +UINT32 Oct6100ApiInitializeInstanceMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + UINT32 ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize API EC channels. */ + ulResult = Oct6100ApiChannelsEchoSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*-----------------------------------------------------------------------------*/ + /* Initialize the API TSI connection structures. */ + ulResult = Oct6100ApiTsiCnctSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*-----------------------------------------------------------------------------*/ + /* Initialize the API conference bridges. */ + ulResult = Oct6100ApiConfBridgeSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the API buffer playout structures. */ + ulResult = Oct6100ApiPlayoutBufferSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the API phasing tssts. */ + ulResult = Oct6100ApiPhasingTsstSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*-----------------------------------------------------------------------------*/ + /* Initialize the API ADPCM channels. */ + ulResult = Oct6100ApiAdpcmChanSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the external memory management structures. */ + ulResult = Oct6100ApiMemorySwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize TSST management stuctures. */ + ulResult = Oct6100ApiTsstSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the mixer management stuctures. */ + ulResult = Oct6100ApiMixerSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the remote debugging session management variables. */ + ulResult = Oct6100ApiRemoteDebuggingSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Configure the interrupt registers. */ + ulResult = Oct6100ApiIsrSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetChipRevisionNum + +Description: Reads the chip's revision number register. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetChipRevisionNum +UINT32 Oct6100ApiGetChipRevisionNum( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT16 usReadData; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get the chip revision number. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.ulReadAddress = cOCT6100_CHIP_ID_REVISION_REG; + ReadParams.pusReadData = &usReadData; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save the info in the API miscellaneous structure. */ + pSharedInfo->MiscVars.usChipId = (UINT16)( usReadData & 0xFF ); + pSharedInfo->MiscVars.usChipRevision = (UINT16)( usReadData >> 8 ); + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckImageFileHeader + +Description: This function check if the image loaded is valid + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckImageFileHeader +UINT32 Oct6100ApiCheckImageFileHeader( + IN tPOCT6100_CHIP_OPEN f_pChipOpen ) +{ + + PUINT8 pszImageInfoStart = NULL; + UINT32 ulStrLen; + + ulStrLen = Oct6100ApiStrLen( (PUINT8)cOCT6100_IMAGE_START_STRING ); + pszImageInfoStart = (PUINT8) Oct6100ApiStrStr(f_pChipOpen->pbyImageFile,(PUINT8)cOCT6100_IMAGE_START_STRING, + f_pChipOpen->pbyImageFile + ulStrLen); + if (pszImageInfoStart == NULL) + return cOCT6100_ERR_OPEN_IMAGE_FILE; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiDecodeKeyAndBist + +Description: This function decodes the key and runs the automatic BIST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiDecodeKeyAndBist +UINT32 Oct6100ApiDecodeKeyAndBist( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT16 ausBistData[ 3 ]; + UINT16 usReadData; + UINT32 ulResult; + BOOL fBitEqual; + UINT32 i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a local pointer to the chip config structure */ + /* contained in the instance structure. */ + pChipConfig = &pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pChipConfig->ulUserChipId; + + /* Set the process context and user chip ID parameters once and for all. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pChipConfig->ulUserChipId; + + /* Write key in CPU internal memory. */ + for(i=0; i<8; i++) + { + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = 0x0000; + if (( i % 2 ) == 0) + { + WriteParams.usWriteData |= ((UINT16)pChipConfig->pbyImageFile[0x100 + ((i/2)*4) + 2]) << 8; + WriteParams.usWriteData |= ((UINT16)pChipConfig->pbyImageFile[0x100 + ((i/2)*4) + 3]) << 0; + } + else + { + WriteParams.usWriteData |= ((UINT16)pChipConfig->pbyImageFile[0x100 + ((i/2)*4) + 0]) << 8; + WriteParams.usWriteData |= ((UINT16)pChipConfig->pbyImageFile[0x100 + ((i/2)*4) + 1]) << 0; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x152; + WriteParams.usWriteData = (UINT16)( 0x8000 | i ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Write one in CPU internal memory. */ + for(i=0; i<8; i++) + { + WriteParams.ulWriteAddress = 0x150; + if (i == 0) + { + WriteParams.usWriteData = 0x0001; + } + else + { + WriteParams.usWriteData = 0x0000; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x152; + WriteParams.usWriteData = (UINT16)( 0x8000 | ( i + 8 )); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Clear memory access registers: */ + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x152; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Run BISTs and key decode. */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0081; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for the key decode PC to clear. */ + ulResult = Oct6100ApiWaitForPcRegisterBit( f_pApiInstance, 0x160, 0, 0, 100000, &fBitEqual ); + if ( TRUE != fBitEqual ) + return cOCT6100_ERR_FATAL_13; + + /* Read the key valid bit to make sure everything is ok. */ + ReadParams.ulReadAddress = 0x160; + ReadParams.pusReadData = &usReadData; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Either the firmware image was not loaded correctly (from pointer given by user) */ + /* or the channel capacity pins of the chip do not match what the firmware is expecting. */ + if ( ( usReadData & 0x4 ) == 0 ) + return cOCT6100_ERR_OPEN_INVALID_FIRMWARE_OR_CAPACITY_PINS; + + /* Read the result of the internal memory bist. */ + ReadParams.ulReadAddress = 0x110; + ReadParams.pusReadData = &ausBistData[ 0 ]; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ReadParams.ulReadAddress = 0x114; + ReadParams.pusReadData = &ausBistData[ 1 ]; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ReadParams.ulReadAddress = 0x118; + ReadParams.pusReadData = &ausBistData[ 2 ]; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if an error was reported. */ + if (ausBistData[0] != 0x0000 || ausBistData[1] != 0x0000 || ausBistData[2] != 0x0000) + return cOCT6100_ERR_OPEN_INTERNAL_MEMORY_BIST; + + /* Put key decoder in powerdown. */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x008A; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBootFc2PllReadCap + +Description: Configures the chip's FC2 PLL. Special version for GetcapacityPins. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiBootFc2PllReadCap( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 aulWaitTime[ 2 ]; + UINT32 ulResult; + UINT32 ulFc2PllDivisor = 0; + UINT32 ulMtDivisor = 0; + UINT32 ulFcDivisor = 0; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pGetCapacityPins->pProcessContext; + + WriteParams.ulUserChipId = f_pGetCapacityPins->ulUserChipId; + + /* First put the chip and main registers in soft-reset. */ + WriteParams.ulWriteAddress = 0x100; + WriteParams.usWriteData = 0x0; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulFc2PllDivisor = 0x1050; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + + /* Setup delay chains. */ + if ( (f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR) || (f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS) ) + { + /* SDRAM */ + WriteParams.ulWriteAddress = 0x1B0; + WriteParams.usWriteData = 0x1003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B2; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B4; + WriteParams.usWriteData = 0x4030; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B6; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else /* if ( cOCT6100_MEM_TYPE_DDR == pChipConfig->byMemoryType ) */ + { + /* DDR */ + WriteParams.ulWriteAddress = 0x1B0; + WriteParams.usWriteData = 0x201F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B2; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B4; + WriteParams.usWriteData = 0x1000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B6; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* udqs */ + WriteParams.ulWriteAddress = 0x1B8; + WriteParams.usWriteData = 0x1003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1BA; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* ldqs */ + WriteParams.ulWriteAddress = 0x1BC; + WriteParams.usWriteData = 0x1000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1BE; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x12C; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x12E; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select fc2pll for fast_clk and mtsclk sources. Select mem_clk_i for afclk. */ + WriteParams.ulWriteAddress = 0x140; + WriteParams.usWriteData = (UINT16)ulMtDivisor; + + if ( f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + WriteParams.usWriteData |= 0x0001; + else + WriteParams.usWriteData |= 0x0004; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x144; + WriteParams.usWriteData = (UINT16)ulFcDivisor; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x13E; + WriteParams.usWriteData = 0x0001; /* Remove reset from above divisors */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select upclk directly as ref source for fc2pll. */ + WriteParams.ulWriteAddress = 0x134; + WriteParams.usWriteData = 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Setup fc2pll. */ + WriteParams.ulWriteAddress = 0x132; + WriteParams.usWriteData = (UINT16)ulFc2PllDivisor; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.usWriteData |= 0x02; /* Raise fb divisor reset. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.usWriteData |= 0x80; /* Raise IDDTN signal.*/ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for fc2pll to stabilize. */ + aulWaitTime[ 0 ] = 2000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Drive mem_clk_o out on proper interface. */ + if ( TRUE == f_pGetCapacityPins->fEnableMemClkOut ) + { + if ( (f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR) || (f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS) ) + { + WriteParams.ulWriteAddress = 0x128; + WriteParams.usWriteData = 0x0301; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_DDR || f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + { + WriteParams.ulWriteAddress = 0x12A; + WriteParams.usWriteData = 0x000F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBootFc2Pll + +Description: Configures the chip's FC2 PLL. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBootFc2Pll +UINT32 Oct6100ApiBootFc2Pll( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 aulWaitTime[ 2 ]; + UINT32 ulResult; + UINT32 ulFc2PllDivisor = 0; + UINT32 ulMtDivisor = 0; + UINT32 ulFcDivisor = 0; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain local pointer to chip configuration structure. */ + pChipConfig = &pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pChipConfig->ulUserChipId; + + /* First put the chip and main registers in soft-reset. */ + WriteParams.ulWriteAddress = 0x100; + WriteParams.usWriteData = 0x0; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select register configuration based on the memory frequency. */ + switch ( f_pApiInstance->pSharedInfo->ChipConfig.ulMemClkFreq ) + { + case 133000000: + ulFc2PllDivisor = 0x1050; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 672; + pSharedInfo->MiscVars.usMaxH100Speed = 124; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x050B; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0516; + + break; + case 125000000: + ulFc2PllDivisor = 0x0F50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 624; + pSharedInfo->MiscVars.usMaxH100Speed = 116; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x04CA; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x04D4; + + break; + case 117000000: + ulFc2PllDivisor = 0x0E50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 576; + pSharedInfo->MiscVars.usMaxH100Speed = 108; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0489; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0492; + + break; + case 108000000: + ulFc2PllDivisor = 0x0D50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 528; + pSharedInfo->MiscVars.usMaxH100Speed = 99; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0408; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0410; + + break; + case 100000000: + ulFc2PllDivisor = 0x0C50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 480; + pSharedInfo->MiscVars.usMaxH100Speed = 91; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x03C8; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x03D0; + + break; + case 92000000: + ulFc2PllDivisor = 0x0B50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 432; + pSharedInfo->MiscVars.usMaxH100Speed = 83; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0387; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x038E; + + break; + case 83000000: + ulFc2PllDivisor = 0x0A50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 384; + pSharedInfo->MiscVars.usMaxH100Speed = 74; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0346; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x034C; + + break; + case 75000000: + ulFc2PllDivisor = 0x0950; + ulMtDivisor = 0x4200; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 336; + pSharedInfo->MiscVars.usMaxH100Speed = 64; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0306; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x030C; + + break; + default: + return cOCT6100_ERR_FATAL_DB; + } + + /* Verify that the max channel is not too big based on the chip frequency. */ + if ( pSharedInfo->ChipConfig.usMaxChannels > pSharedInfo->MiscVars.usMaxNumberOfChannels ) + return cOCT6100_ERR_OPEN_MAX_ECHO_CHANNELS; + + /* Setup delay chains. */ + if ( (pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_SDR) || (pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS) ) + { + /* SDRAM */ + WriteParams.ulWriteAddress = 0x1B0; + WriteParams.usWriteData = 0x1003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B2; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B4; + WriteParams.usWriteData = 0x4030; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B6; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else /* if ( cOCT6100_MEM_TYPE_DDR == pChipConfig->byMemoryType ) */ + { + /* DDR */ + WriteParams.ulWriteAddress = 0x1B0; + WriteParams.usWriteData = 0x201F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B2; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B4; + WriteParams.usWriteData = 0x1000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B6; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* udqs */ + WriteParams.ulWriteAddress = 0x1B8; + WriteParams.usWriteData = 0x1003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1BA; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* ldqs */ + WriteParams.ulWriteAddress = 0x1BC; + WriteParams.usWriteData = 0x1000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1BE; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x12C; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x12E; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select fc2pll for fast_clk and mtsclk sources. Select mem_clk_i for afclk. */ + WriteParams.ulWriteAddress = 0x140; + WriteParams.usWriteData = (UINT16)ulMtDivisor; + + if ( f_pApiInstance->pSharedInfo->ChipConfig.byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + WriteParams.usWriteData |= 0x0001; + else + WriteParams.usWriteData |= 0x0004; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x144; + WriteParams.usWriteData = (UINT16)ulFcDivisor; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x13E; + WriteParams.usWriteData = 0x0001; /* Remove reset from above divisors */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select upclk directly as ref source for fc2pll. */ + WriteParams.ulWriteAddress = 0x134; + WriteParams.usWriteData = 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Setup fc2pll. */ + WriteParams.ulWriteAddress = 0x132; + WriteParams.usWriteData = (UINT16)ulFc2PllDivisor; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.usWriteData |= 0x02; /* Raise fb divisor reset. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.usWriteData |= 0x80; /* Raise IDDTN signal.*/ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for fc2pll to stabilize. */ + aulWaitTime[ 0 ] = 2000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Drive mem_clk_o out on proper interface. */ + if ( TRUE == pChipConfig->fEnableMemClkOut ) + { + if ( (pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_SDR) || (pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS) ) + { + WriteParams.ulWriteAddress = 0x128; + WriteParams.usWriteData = 0x0301; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_DDR || pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + { + WriteParams.ulWriteAddress = 0x12A; + WriteParams.usWriteData = 0x000F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiProgramFc1PllReadCap + +Description: Configures the chip's FC1 PLL. Special version for getCapacityPins. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiProgramFc1PllReadCap( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 aulWaitTime[ 2 ]; + UINT32 ulResult; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pGetCapacityPins->ulUserChipId; + + /* Programm P/Z bits. */ + WriteParams.ulWriteAddress = 0x130; + + if ( f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + WriteParams.usWriteData = 0x0041; + else + WriteParams.usWriteData = 0x0040; + + WriteParams.usWriteData |= ( f_pGetCapacityPins->ulMemoryType << 8 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Raise FB divisor. */ + WriteParams.usWriteData |= 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Raise IDDTN. */ + WriteParams.usWriteData |= 0x0080; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for fc1pll to stabilize. */ + aulWaitTime[ 0 ] = 2000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable all the clock domains to do reset procedure. */ + WriteParams.ulWriteAddress = 0x186; + WriteParams.usWriteData = 0x015F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + aulWaitTime[ 0 ] = 15000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiProgramFc1Pll + +Description: Configures the chip's FC1 PLL. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiProgramFc1Pll +UINT32 Oct6100ApiProgramFc1Pll( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 aulWaitTime[ 2 ]; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain local pointer to chip configuration structure. */ + pChipConfig = &pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pChipConfig->ulUserChipId; + + /* Programm P/Z bits. */ + WriteParams.ulWriteAddress = 0x130; + + if ( f_pApiInstance->pSharedInfo->ChipConfig.byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + WriteParams.usWriteData = 0x0041; + else + WriteParams.usWriteData = 0x0040; + + WriteParams.usWriteData |= ( pChipConfig->byMemoryType << 8 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Raise FB divisor. */ + WriteParams.usWriteData |= 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Raise IDDTN. */ + WriteParams.usWriteData |= 0x0080; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for fc1pll to stabilize. */ + aulWaitTime[ 0 ] = 2000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable all the clock domains to do reset procedure. */ + WriteParams.ulWriteAddress = 0x186; + WriteParams.usWriteData = 0x015F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + aulWaitTime[ 0 ] = 15000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBootFc1Pll + +Description: Boot the chip's FC1 PLL. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBootFc1Pll +UINT32 Oct6100ApiBootFc1Pll( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 aulWaitTime[ 2 ]; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain local pointer to chip configuration structure. */ + pChipConfig = &pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pChipConfig->ulUserChipId; + + /* Force bist_clk also (it too is used on resetable flops). */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0188; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Force all cpu clocks on chariot controllers. */ + WriteParams.ulWriteAddress = 0x182; + WriteParams.usWriteData = 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x184; + WriteParams.usWriteData = 0x0202; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + aulWaitTime[ 0 ] = 1000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Remove the reset on the entire chip and disable CPU access caching. */ + WriteParams.ulWriteAddress = 0x100; + WriteParams.usWriteData = 0x2003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Remove the bist_clk. It is no longer needed.*/ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0088; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Disable all clks to prepare for bist clock switchover. */ + WriteParams.ulWriteAddress = 0x182; + WriteParams.usWriteData = 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x186; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x184; + WriteParams.usWriteData = 0x0101; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Deassert bist_active */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0008; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Change CPU interface to normal mode (from boot mode). */ + WriteParams.ulWriteAddress = 0x154; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Give a couple of BIST clock cycles to turn off the BIST permanently. */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0108; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Turn BIST clock off for the last time. */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0008; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reset procedure done! */ + + /* Enable mclk for cpu interface and external memory controller. */ + WriteParams.ulWriteAddress = 0x186; + WriteParams.usWriteData = 0x0100; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiLoadImage + +Description: This function writes the firmware image in the external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiLoadImage +UINT32 Oct6100ApiLoadImage( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_BURST_PARAMS BurstParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT32 ulTempPtr; + UINT32 ulNumWrites; + PUINT16 pusSuperArray; + unsigned char const *pbyImageFile; + UINT32 ulByteCount = 0; + UINT16 usReadData; + UINT32 ulAddressOfst; + UINT32 i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Breakdown image into subcomponents. */ + ulTempPtr = cOCT6100_IMAGE_FILE_BASE + cOCT6100_IMAGE_AF_CST_OFFSET; + + for(i=0;iImageRegion[ i ].ulPart1Size = pSharedInfo->ChipConfig.pbyImageFile[ 0x110 + ( i * 4 ) + 0 ]; + pSharedInfo->ImageRegion[ i ].ulPart2Size = pSharedInfo->ChipConfig.pbyImageFile[ 0x110 + ( i * 4 ) + 1 ]; + pSharedInfo->ImageRegion[ i ].ulClockInfo = pSharedInfo->ChipConfig.pbyImageFile[ 0x110 + ( i * 4 ) + 2 ]; + pSharedInfo->ImageRegion[ i ].ulReserved = pSharedInfo->ChipConfig.pbyImageFile[ 0x110 + ( i * 4 ) + 3 ]; + + if (i == 0) /* AF constant. */ + { + pSharedInfo->ImageRegion[ i ].ulPart1BaseAddress = ulTempPtr & 0x07FFFFFF; + pSharedInfo->ImageRegion[ i ].ulPart2BaseAddress = 0; + + ulTempPtr += ( pSharedInfo->ImageRegion[ i ].ulPart1Size * 612 ); + } + else if (i == 1) /* NLP image */ + { + pSharedInfo->ImageRegion[ i ].ulPart1BaseAddress = ulTempPtr & 0x07FFFFFF; + pSharedInfo->ImageRegion[ i ].ulPart2BaseAddress = 0; + + ulTempPtr += ( pSharedInfo->ImageRegion[ i ].ulPart1Size * 2056 ); + } + else /* Others */ + { + pSharedInfo->ImageRegion[ i ].ulPart1BaseAddress = ulTempPtr & 0x07FFFFFF; + ulTempPtr += ( pSharedInfo->ImageRegion[ i ].ulPart1Size * 2064 ); + + pSharedInfo->ImageRegion[ i ].ulPart2BaseAddress = ulTempPtr & 0x07FFFFFF; + ulTempPtr += ( pSharedInfo->ImageRegion[ i ].ulPart2Size * 2448 ); + } + } + + /* Write the image in external memory. */ + ulNumWrites = pSharedInfo->ChipConfig.ulImageSize / 2; + + BurstParams.ulWriteAddress = cOCT6100_IMAGE_FILE_BASE; + BurstParams.pusWriteData = pSharedInfo->MiscVars.ausSuperArray; + + pusSuperArray = pSharedInfo->MiscVars.ausSuperArray; + pbyImageFile = pSharedInfo->ChipConfig.pbyImageFile; + + while ( ulNumWrites != 0 ) + { + if ( ulNumWrites >= pSharedInfo->ChipConfig.usMaxRwAccesses ) + BurstParams.ulWriteLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + else + BurstParams.ulWriteLength = ulNumWrites; + + for ( i = 0; i < BurstParams.ulWriteLength; i++ ) + { + pusSuperArray[ i ] = ( UINT16 )(( pbyImageFile [ ulByteCount++ ]) << 8); + pusSuperArray[ i ] |= ( UINT16 )pbyImageFile [ ulByteCount++ ]; + } + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + BurstParams.ulWriteAddress += 2 * BurstParams.ulWriteLength; + ulNumWrites -= BurstParams.ulWriteLength; + } + + /* Perform a serie of reads to make sure the image was correclty written into memory. */ + ulAddressOfst = ( pSharedInfo->ChipConfig.ulImageSize / 2 ) & 0xFFFFFFFE; + while ( ulAddressOfst != 0 ) + { + ReadParams.ulReadAddress = cOCT6100_IMAGE_FILE_BASE + ulAddressOfst; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( (usReadData >> 8) != pbyImageFile[ ulAddressOfst ] ) + return cOCT6100_ERR_OPEN_IMAGE_WRITE_FAILED; + + ulAddressOfst = (ulAddressOfst / 2) & 0xFFFFFFFE; + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCpuRegisterBistReadCap + +Description: Tests the operation of the CPU registers. Special Version for + GetCapacityPins + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiCpuRegisterBistReadCap( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins + ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT16 i; + UINT16 usReadData; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pGetCapacityPins->ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pGetCapacityPins->ulUserChipId; + + /* Assign read data pointer that will be used throughout the function. */ + ReadParams.pusReadData = &usReadData; + + /* Start with a walking bit test. */ + for ( i = 0; i < 16; i ++ ) + { + /* Write at address 0x150.*/ + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = (UINT16)( 0x1 << i ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write at address 0x180.*/ + WriteParams.ulWriteAddress = 0x180; + WriteParams.usWriteData = (UINT16)( 0x1 << ( 15 - i ) ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now read back the two registers to make sure the acceses were successfull. */ + ReadParams.ulReadAddress = 0x150; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != ( 0x1 << i ) ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + + ReadParams.ulReadAddress = 0x180; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != ( 0x1 << ( 15 - i ) ) ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + } + + /* Write at address 0x150. */ + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = 0xCAFE; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write at address 0x180. */ + WriteParams.ulWriteAddress = 0x180; + WriteParams.usWriteData = 0xDECA; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now read back the two registers to make sure the acceses were successfull. */ + ReadParams.ulReadAddress = 0x150; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != 0xCAFE ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + + ReadParams.ulReadAddress = 0x180; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != 0xDECA ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + + return cOCT6100_ERR_OK; +} +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCpuRegisterBist + +Description: Tests the operation of the CPU registers. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCpuRegisterBist +UINT32 Oct6100ApiCpuRegisterBist( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT16 i; + UINT16 usReadData; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Assign read data pointer that will be used throughout the function. */ + ReadParams.pusReadData = &usReadData; + + /* Start with a walking bit test. */ + for ( i = 0; i < 16; i ++ ) + { + /* Write at address 0x150.*/ + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = (UINT16)( 0x1 << i ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write at address 0x180.*/ + WriteParams.ulWriteAddress = 0x180; + WriteParams.usWriteData = (UINT16)( 0x1 << ( 15 - i ) ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now read back the two registers to make sure the acceses were successfull. */ + ReadParams.ulReadAddress = 0x150; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != ( 0x1 << i ) ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + + ReadParams.ulReadAddress = 0x180; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != ( 0x1 << ( 15 - i ) ) ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + } + + /* Write at address 0x150. */ + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = 0xCAFE; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write at address 0x180. */ + WriteParams.ulWriteAddress = 0x180; + WriteParams.usWriteData = 0xDECA; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now read back the two registers to make sure the acceses were successfull. */ + ReadParams.ulReadAddress = 0x150; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != 0xCAFE ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + + ReadParams.ulReadAddress = 0x180; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != 0xDECA ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBootSdram + +Description: Configure and test the SDRAM. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBootSdram +UINT32 Oct6100ApiBootSdram( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + UINT16 usWriteData23E; + UINT16 usWriteData230; + UINT32 i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get local pointer to the chip configuration structure.*/ + pChipConfig = &f_pApiInstance->pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + usWriteData23E = 0x0000; + usWriteData230 = 0x0000; + + if ( (pSharedInfo->ChipConfig.byMemoryType == cOCT6100_MEM_TYPE_SDR) || (pSharedInfo->ChipConfig.byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS) ) + { + /* SDRAM: */ + switch( pChipConfig->ulMemoryChipSize ) + { + case cOCT6100_MEMORY_CHIP_SIZE_8MB: + usWriteData230 |= ( cOCT6100_16MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_16MB: + usWriteData230 |= ( cOCT6100_32MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_32MB: + usWriteData230 |= ( cOCT6100_64MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_64MB: + usWriteData230 |= ( cOCT6100_128MB_MEMORY_BANKS << 2 ); + break; + default: + return cOCT6100_ERR_FATAL_16; + } + + usWriteData230 |= 0x0002; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Precharge all banks. */ + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0010; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Program the mode register. */ + usWriteData23E = 0x0030; + WriteParams.usWriteData = usWriteData23E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0000; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Do CBR refresh (twice) */ + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0040; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else + { + /* DDR: */ + switch( pChipConfig->ulMemoryChipSize ) + { + case cOCT6100_MEMORY_CHIP_SIZE_16MB: + usWriteData230 |= ( cOCT6100_16MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_32MB: + usWriteData230 |= ( cOCT6100_32MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_64MB: + usWriteData230 |= ( cOCT6100_64MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_128MB: + usWriteData230 |= ( cOCT6100_128MB_MEMORY_BANKS << 2 ); + break; + default: + return cOCT6100_ERR_FATAL_17; + } + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Precharge all banks. */ + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0010; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Program DDR mode register. */ + usWriteData23E = 0x4000; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0000; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Program SDR mode register. */ + usWriteData23E = 0x0161; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0000; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Precharge all banks. */ + usWriteData23E = 0xFFFF; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0010; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Do CBR refresh (twice) */ + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0040; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle.*/ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Program SDR mode register. */ + usWriteData23E = 0x0061; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0000; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the refresh frequency. */ + WriteParams.ulWriteAddress = 0x242; + WriteParams.usWriteData = 0x0400; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x244; + WriteParams.usWriteData = 0x0200; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x248; + WriteParams.usWriteData = 0x800; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x246; + WriteParams.usWriteData = 0x0012; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable the SDRAM and refreshes. */ + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0001; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x246; + WriteParams.usWriteData = 0x0013; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiEnableClocks + +Description: This function will disable clock masking for all the modules + of the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiEnableClocks +UINT32 Oct6100ApiEnableClocks( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Initialize the process context and user chip ID once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Enable tdmie / adpcm mclk clocks. */ + WriteParams.ulWriteAddress = 0x186; + WriteParams.usWriteData = 0x015F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the DQS register for the DDR memory */ + WriteParams.ulWriteAddress = 0x180; + WriteParams.usWriteData = 0xFF00; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable pgsp chariot clocks */ + WriteParams.ulWriteAddress = 0x182; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable af/mt chariot clocks */ + WriteParams.ulWriteAddress = 0x184; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiProgramNLP + +Description: This function will write image values to configure the NLP. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiProgramNLP +UINT32 Oct6100ApiProgramNLP( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + UINT32 ulResult; + UINT16 usReadData; + UINT16 usReadHighData; + BOOL fBitEqual; + UINT32 ulEgoEntry[4]; + UINT32 ulTempAddress; + UINT32 ulAfCpuUp = FALSE; + UINT32 i; + UINT32 ulLoopCounter = 0; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get local pointer to the chip configuration structure.*/ + pChipConfig = &f_pApiInstance->pSharedInfo->ChipConfig; + + /* Initialize the process context and user chip ID once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Initialize the process context and user chip ID once and for all. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + if ( pSharedInfo->ChipConfig.fEnableProductionBist == TRUE ) + { + UINT32 ulReadData; + UINT32 ulBitPattern; + UINT32 j, k; + + /* Since the pouch section (256 bytes) will not be tested by the firmware, */ + /* the API has to make sure this section is working correctly. */ + for ( k = 0; k < 2; k ++ ) + { + if ( k == 0 ) + ulBitPattern = 0x1; + else + ulBitPattern = 0xFFFFFFFE; + + for ( j = 0; j < 32; j ++ ) + { + /* Write the DWORDs. */ + for ( i = 0; i < 64; i ++ ) + { + ulResult = Oct6100ApiWriteDword( f_pApiInstance, cOCT6100_POUCH_BASE + i * 4, ulBitPattern << j ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Read the DWORDs. */ + for ( i = 0; i < 64; i ++ ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, cOCT6100_POUCH_BASE + i * 4, &ulReadData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the value matches. */ + if ( ( ulBitPattern << j ) != ulReadData ) + return cOCT6100_ERR_OPEN_PRODUCTION_BIST_POUCH_ERROR; + } + } + } + } + + /* Write the image info in the chip. */ + WriteParams.ulWriteAddress = cOCT6100_PART1_END_STATICS_BASE; + WriteParams.usWriteData = (UINT16)( ( pSharedInfo->ImageRegion[ 0 ].ulPart1BaseAddress >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( pSharedInfo->ImageRegion[ 0 ].ulPart1BaseAddress & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + for( i = 0; i < 8; i++ ) + { + if ( pSharedInfo->ImageRegion[ i + 2 ].ulPart1Size != 0 ) + { + WriteParams.ulWriteAddress = cOCT6100_PART1_END_STATICS_BASE + 0x4 + ( i * 0xC ); + WriteParams.usWriteData = (UINT16)(( pSharedInfo->ImageRegion[ i + 2 ].ulPart1BaseAddress >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( pSharedInfo->ImageRegion[ i + 2 ].ulPart1BaseAddress & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pSharedInfo->ImageRegion[ i + 2 ].ulPart2Size != 0 ) + { + WriteParams.ulWriteAddress = cOCT6100_PART1_END_STATICS_BASE + 0x4 + ( i * 0xC ) + 4; + WriteParams.usWriteData = (UINT16)(( pSharedInfo->ImageRegion[ i + 2 ].ulPart2BaseAddress >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( pSharedInfo->ImageRegion[ i + 2 ].ulPart2BaseAddress & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + WriteParams.ulWriteAddress = cOCT6100_PART1_END_STATICS_BASE + 0x4 + ( i * 0xC ) + 8; + WriteParams.usWriteData = 0x0000; + WriteParams.usWriteData |= ( pSharedInfo->ImageRegion[ i + 2 ].ulPart1Size << 8 ); + WriteParams.usWriteData |= pSharedInfo->ImageRegion[ i + 2 ].ulPart2Size; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = 0x0000; + WriteParams.usWriteData |= ( pSharedInfo->ImageRegion[ i + 2 ].ulClockInfo << 8 ); + WriteParams.usWriteData |= pSharedInfo->ImageRegion[ i + 2 ].ulReserved; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Put NLP in config mode. */ + WriteParams.ulWriteAddress = 0x2C2; + WriteParams.usWriteData = 0x160E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x692; + WriteParams.usWriteData = 0x010A; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Upload the up to 8 NLP pages + 1 AF page (for timing reasons). */ + for ( i = 0; i < pSharedInfo->ImageRegion[ 1 ].ulPart1Size; i++ ) + { + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 1 ].ulPart1BaseAddress + 1028 * ( i * 2 ), 0x1280, 1024, &(ulEgoEntry[0])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 1 ].ulPart1BaseAddress + 1028 * (( i * 2 ) + 1 ), 0x1680, 1024, &(ulEgoEntry[2])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiRunEgo( f_pApiInstance, FALSE, 2, ulEgoEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Shift mt chariot memories. This process will complete by the time */ + /* the next LSU transfer is done. */ + WriteParams.ulWriteAddress = 0x692; + WriteParams.usWriteData = 0x010B; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiWaitForPcRegisterBit( f_pApiInstance, 0x692, 0, 0, 100000, &fBitEqual ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + if ( TRUE != fBitEqual ) + return cOCT6100_ERR_FATAL_1A; + } + + /* 1 AF page (for timing reasons). */ + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 2 ].ulPart1BaseAddress + (516 * 0), 0x1280, 512, &(ulEgoEntry[0])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 2 ].ulPart1BaseAddress + (516 * 1), 0x1480, 512, &(ulEgoEntry[2])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiRunEgo( f_pApiInstance, FALSE, 2, ulEgoEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 2 ].ulPart1BaseAddress + (516 * 2), 0x1680, 512, &(ulEgoEntry[0])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 2 ].ulPart1BaseAddress + (516 * 3), 0x1880, 512, &(ulEgoEntry[2])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiRunEgo( f_pApiInstance, FALSE, 2, ulEgoEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write constant memory init context position in channel "672" for pgsp. */ + WriteParams.ulWriteAddress = 0x71A; + WriteParams.usWriteData = 0x8000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set fixed PGSP event_in base address to 800 on a 2k boundary */ + WriteParams.ulWriteAddress = 0x716; + WriteParams.usWriteData = 0x800 >> 11; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set fixed PGSP event_out to 0x2C0000h on a 16k boundary */ + WriteParams.ulWriteAddress = 0x71C; + WriteParams.usWriteData = 0x2C0000 >> 14; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Give chariot control of the chip. */ + WriteParams.ulWriteAddress = 0x712; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + 0x2C0000 + 0xC; + ulTempAddress = 0x300000 + 0x0800; + WriteParams.usWriteData = (UINT16)( ( ulTempAddress >> 16 ) & 0x07FF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + 0x2C0000 + 0xE; + WriteParams.usWriteData = (UINT16)( ( ulTempAddress >> 0 ) & 0xFF00 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write the init PGSP event in place. */ + WriteParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + 0x800; + WriteParams.usWriteData = 0x0200; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + 0x802; + WriteParams.usWriteData = 0x02A0; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Also write the register 710, which tells PGSP how many tones are supported. */ + WriteParams.ulWriteAddress = 0x710; + WriteParams.usWriteData = 0x0000; + WriteParams.usWriteData |= pChipConfig->pbyImageFile[ 0x7FA ] << 8; + WriteParams.usWriteData |= pChipConfig->pbyImageFile[ 0x7FB ] << 0; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Start both processors in the NLP. */ + WriteParams.ulWriteAddress = 0x373FE; + WriteParams.usWriteData = 0x00FF; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x37BFE; + WriteParams.usWriteData = 0x00FE; /* Tell processor 1 to just go to sleep. */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x37FC6; + WriteParams.usWriteData = 0x8004; /* First PC.*/ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x37FD0; + WriteParams.usWriteData = 0x0002; /* Take out of reset. */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x37FD2; + WriteParams.usWriteData = 0x0002; /* Take out of reset. */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Start processor in the AF. */ + for ( i = 0; i < 16; i ++ ) + { + WriteParams.ulWriteAddress = cOCT6100_POUCH_BASE + ( i * 2 ); + if ( i == 9 ) + { + if ( pSharedInfo->ChipConfig.fEnableProductionBist == TRUE ) + { + if (pSharedInfo->ChipConfig.ulProductionBistMode == cOCT6100_PRODUCTION_BIST_SHORT) + WriteParams.usWriteData = cOCT6100_PRODUCTION_SHORT_BOOT_TYPE; + else + WriteParams.usWriteData = cOCT6100_PRODUCTION_BOOT_TYPE; + } + else + { + WriteParams.usWriteData = cOCT6100_AF_BOOT_TYPE; + } + } + else + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Check if the production BIST mode was requested. */ + if ( pSharedInfo->ChipConfig.fEnableProductionBist == TRUE ) + { + UINT32 ulTotalElements = 3; + UINT32 ulCrcKey; + UINT32 aulMessage[ 4 ]; + UINT32 ulWriteAddress = 0x20 + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + + /* Magic key. */ + aulMessage[ 0 ] = 0xCAFECAFE; + /* Memory size. */ + aulMessage[ 1 ] = pSharedInfo->MiscVars.ulTotalMemSize; + /* Loop count. */ + aulMessage[ 2 ] = pSharedInfo->ChipConfig.ulNumProductionBistLoops; + /* CRC initialized. */ + aulMessage[ 3 ] = 0; + + ulResult = Oct6100ApiProductionCrc( f_pApiInstance, aulMessage, ulTotalElements, &ulCrcKey ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + aulMessage[ 3 ] = ulCrcKey; + + /* Write the message to the external memory. */ + for ( i = 0; i < ulTotalElements + 1; i ++ ) + { + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulWriteAddress + i * 4, aulMessage[ i ] ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + WriteParams.ulWriteAddress = 0xFFFC6; + WriteParams.usWriteData = 0x1284; /* First PC.*/ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0xFFFD0; + WriteParams.usWriteData = 0x0002; /* Take out of reset. */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + while ( ulAfCpuUp == FALSE ) + { + if ( ulAfCpuUp == FALSE ) + { + ReadParams.ulReadAddress = cOCT6100_POUCH_BASE; + ReadParams.pusReadData = &usReadHighData; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ReadParams.ulReadAddress += 2; + ReadParams.pusReadData = &usReadData; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( pSharedInfo->ChipConfig.fEnableProductionBist == TRUE ) + { + /* Should read 0x0007 when bisting. */ + if ( (( usReadHighData & 0xFFFF ) == cOCT6100_PRODUCTION_BOOT_TYPE) || + (( usReadHighData & 0xFFFF ) == cOCT6100_PRODUCTION_SHORT_BOOT_TYPE) ) + { + /* Verify if the bist has started successfully. */ + if ( ( usReadData & 0xFFFF ) == 0x0002 ) + return cOCT6100_ERR_OPEN_PRODUCTION_BIST_CONF_FAILED; + else if ( ( usReadData & 0xFFFF ) != 0xEEEE ) + return cOCT6100_ERR_OPEN_PRODUCTION_BOOT_FAILED; + + ulAfCpuUp = TRUE; + } + } + else /* if ( pSharedInfo->ChipConfig.fEnableProductionBist == FALSE ) */ + { + if ( ( usReadHighData & 0xFFFF ) == cOCT6100_AF_BOOT_TYPE ) + { + /* Verify if the bist succeeded. */ + if ( ( usReadData & 0xFFFF ) != 0x0000 ) + return cOCT6100_ERR_OPEN_FUNCTIONAL_BIST_FAILED; + + ulAfCpuUp = TRUE; + } + } + } + + ulLoopCounter++; + + if ( ulLoopCounter == cOCT6100_MAX_LOOP_CPU_TIMEOUT ) + return cOCT6100_ERR_OPEN_AF_CPU_TIMEOUT; + } + + /* Return NLP in operationnal mode. */ + WriteParams.ulWriteAddress = 0x2C2; + WriteParams.usWriteData = 0x060E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x692; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiSetH100Register + +Description: This function will configure the H.100 registers. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiSetH100Register +UINT32 Oct6100ApiSetH100Register( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + UINT32 i; + UINT32 ulOffset; + BOOL fAllStreamAt2Mhz = TRUE; + const UINT16 ausAdpcmResetContext[32] = { 0x1100, 0x0220, 0x0000, 0x0000, 0x0000, 0x0020, 0x0000, 0x0000, 0x0008, 0x0000, 0x0000, 0x0100, 0x0000, 0x0020, 0x0000, 0x0000, 0x0000, 0x0002, 0x0000, 0x0000, 0x0040, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x0000, 0x0010, 0x0000, 0x0000, 0x0000}; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get local pointer to the chip configuration structure. */ + pChipConfig = &f_pApiInstance->pSharedInfo->ChipConfig; + + /* Initialize the process context and user chip ID once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Set the Global OE bit. */ + WriteParams.ulWriteAddress = 0x300; + WriteParams.usWriteData = 0x0004; + + /* Set the number of streams. */ + switch( pChipConfig->byMaxTdmStreams ) + { + case 32: + WriteParams.usWriteData |= ( 0 << 3 ); + break; + case 16: + WriteParams.usWriteData |= ( 1 << 3 ); + break; + case 8: + WriteParams.usWriteData |= ( 2 << 3 ); + break; + case 4: + WriteParams.usWriteData |= ( 3 << 3 ); + break; + default: + break; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the stream frequency. */ + WriteParams.ulWriteAddress = 0x330; + WriteParams.usWriteData = 0x0000; + for ( i = 0; i < (UINT32)(pChipConfig->byMaxTdmStreams / 4); i++) + { + ulOffset = i*2; + switch( pChipConfig->aulTdmStreamFreqs[ i ] ) + { + case cOCT6100_TDM_STREAM_FREQ_2MHZ: + WriteParams.usWriteData |= ( 0x0 << ulOffset ); + break; + case cOCT6100_TDM_STREAM_FREQ_4MHZ: + WriteParams.usWriteData |= ( 0x1 << ulOffset ); + fAllStreamAt2Mhz = FALSE; + break; + case cOCT6100_TDM_STREAM_FREQ_8MHZ: + WriteParams.usWriteData |= ( 0x2 << ulOffset ); + fAllStreamAt2Mhz = FALSE; + break; + default: + break; + } + } + + /* Set the stream to 16 MHz if the fast H.100 mode is selected. */ + if ( pChipConfig->fEnableFastH100Mode == TRUE ) + { + fAllStreamAt2Mhz = FALSE; + WriteParams.usWriteData = 0xFFFF; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + { + /* Make the chip track both clock A and B to perform fast H.100 mode. */ + WriteParams.ulWriteAddress = 0x322; + WriteParams.usWriteData = 0x0004; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable the fast H.100 mode. */ + WriteParams.ulWriteAddress = 0x332; + WriteParams.usWriteData = 0x0003; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + WriteParams.ulWriteAddress = 0x376; + WriteParams.usWriteData = (UINT16)( pSharedInfo->MiscVars.usTdmClkBoundary ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select delay for early clock (90 and 110). */ + WriteParams.ulWriteAddress = 0x378; + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + WriteParams.usWriteData = 0x000A; + else + { + /* Set the TDM sampling. */ + if ( pSharedInfo->ChipConfig.byTdmSampling == cOCT6100_TDM_SAMPLE_AT_RISING_EDGE ) + { + WriteParams.usWriteData = 0x0AF0; + } + else if ( pSharedInfo->ChipConfig.byTdmSampling == cOCT6100_TDM_SAMPLE_AT_FALLING_EDGE ) + { + WriteParams.usWriteData = 0x0A0F; + } + else /* pSharedInfo->ChipConfig.ulTdmSampling == cOCT6100_TDM_SAMPLE_AT_3_QUARTERS */ + { + WriteParams.usWriteData = 0x0A08; + } + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Protect chip by preventing too rapid timeslot arrival (mclk == 133 MHz). */ + WriteParams.ulWriteAddress = 0x37A; + WriteParams.usWriteData = (UINT16)pSharedInfo->MiscVars.usMaxH100Speed; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Allow H.100 TS to progress. */ + WriteParams.ulWriteAddress = 0x382; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set by-pass mode. */ + WriteParams.ulWriteAddress = 0x50E; + WriteParams.usWriteData = 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* TDMIE bits. */ + WriteParams.ulWriteAddress = 0x500; + WriteParams.usWriteData = 0x0003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write normal ADPCM reset values in ADPCM context 1344. */ + for(i=0;i<32;i++) + { + WriteParams.ulWriteAddress = 0x140000 + ( 0x40 * 1344 ) + ( i * 2 ); + WriteParams.usWriteData = ausAdpcmResetContext[i]; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Make sure delay flops are configured correctly if all streams are at 2 MHz. */ + if ( fAllStreamAt2Mhz == TRUE ) + { + /* Setup H.100 sampling to lowest value. */ + WriteParams.ulWriteAddress = 0x144; + WriteParams.usWriteData = 0x4041; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x378; + WriteParams.usWriteData = 0x0A00; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteMiscellaneousRegisters + +Description: This function will write to various registers to activate the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteMiscellaneousRegisters +UINT32 Oct6100ApiWriteMiscellaneousRegisters( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Initialize the process context and user chip ID once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Free the interrupt pin of the chip (i.e. remove minimum time requirement between interrupts). */ + WriteParams.ulWriteAddress = 0x214; + WriteParams.usWriteData = 0x0000; + if ( f_pApiInstance->pSharedInfo->ChipConfig.byInterruptPolarity == cOCT6100_ACTIVE_HIGH_POLARITY ) + WriteParams.usWriteData |= 0x4000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write MT chariot interval */ + WriteParams.ulWriteAddress = 0x2C2; + if ( f_pApiInstance->pSharedInfo->ImageInfo.usMaxNumberOfChannels > 640 ) + WriteParams.usWriteData = 0x05EA; + else if ( f_pApiInstance->pSharedInfo->ImageInfo.usMaxNumberOfChannels > 513 ) + WriteParams.usWriteData = 0x0672; + else /* if ( f_pApiInstance->pSharedInfo->ImageInfo.usMaxNumberOfChannels <= 513 ) */ + WriteParams.usWriteData = 0x0750; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write set second part5 time. */ + WriteParams.ulWriteAddress = 0x2C4; + WriteParams.usWriteData = 0x04A0; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write CPU bucket timer to guarantee 200 cycles between each CPU access. */ + WriteParams.ulWriteAddress = 0x234; + WriteParams.usWriteData = 0x0804; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x236; + WriteParams.usWriteData = 0x0100; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCreateSerializeObjects + +Description: Creates a handle to each serialization object used by the API. + + Note that in a multi-process system the user's process context + structure pointer is needed by this function. Thus, the + pointer must be valid. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulUserChipId User chip ID for this serialization object. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCreateSerializeObjects +UINT32 Oct6100ApiCreateSerializeObjects( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulUserChipId ) +{ + tOCT6100_CREATE_SERIALIZE_OBJECT CreateSerObj; + UINT32 ulResult; + CHAR szSerObjName[ 64 ] = "Oct6100ApiXXXXXXXXApiSerObj"; + + + /* Set some parameters of the create structure once and for all. */ + CreateSerObj.pProcessContext = f_pApiInstance->pProcessContext; + CreateSerObj.pszSerialObjName = szSerObjName; + + /*----------------------------------------------------------------------*/ + /* Set the chip ID in the semaphore name. */ + szSerObjName[ 10 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 28 ) & 0xFF ); + szSerObjName[ 11 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 24 ) & 0xFF ); + szSerObjName[ 12 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 20 ) & 0xFF ); + szSerObjName[ 13 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 16 ) & 0xFF ); + szSerObjName[ 14 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 12 ) & 0xFF ); + szSerObjName[ 15 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 8 ) & 0xFF ); + szSerObjName[ 16 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 4 ) & 0xFF ); + szSerObjName[ 17 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 0 ) & 0xFF ); + + ulResult = Oct6100UserCreateSerializeObject( &CreateSerObj ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + f_pApiInstance->ulApiSerObj = CreateSerObj.ulSerialObjHndl; + /*----------------------------------------------------------------------*/ + + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiDestroySerializeObjects + +Description: Destroy handles to each serialization object used by the API. + + Note that in a multi-process system the user's process context + structure pointer is needed by this function. Thus, the + pointer must be valid. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiDestroySerializeObjects +UINT32 Oct6100ApiDestroySerializeObjects( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_DESTROY_SERIALIZE_OBJECT DestroySerObj; + UINT32 ulResult; + + /* Set some parameters of the create structure once and for all. */ + DestroySerObj.pProcessContext = f_pApiInstance->pProcessContext; + DestroySerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + + ulResult = Oct6100UserDestroySerializeObject( &DestroySerObj ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRunEgo + +Description: Private function used to communicate with the internal processors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_fStoreFlag Type of access performed. (Load or Store) +f_ulNumEntry Number of access. +f_aulEntry Array of access to perform. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRunEgo +UINT32 Oct6100ApiRunEgo( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN BOOL f_fStoreFlag, + IN UINT32 f_ulNumEntry, + OUT PUINT32 f_aulEntry ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT32 aulCpuLsuCmd[ 2 ]; + UINT16 usReadData; + UINT32 i; + BOOL fConditionFlag = TRUE; + UINT32 ulLoopCounter = 0; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* No more than 2 entries may be requested. */ + if ( f_ulNumEntry > 2 ) + return cOCT6100_ERR_FATAL_1B; + + /* Write the requested entries at address reserved for CPU. */ + for( i = 0; i < f_ulNumEntry; i++ ) + { + WriteParams.ulWriteAddress = cOCT6100_PART1_API_SCRATCH_PAD + ( 0x8 * i ); + WriteParams.usWriteData = (UINT16)(( f_aulEntry[ i * 2 ] >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( f_aulEntry[ i * 2 ] & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)(( f_aulEntry[ (i * 2) + 1] >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( f_aulEntry[ (i * 2) + 1] & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Preincrement code point. */ + pSharedInfo->MiscVars.usCodepoint++; + + /* Create DWORD 0 of command. */ + aulCpuLsuCmd[0] = 0x00000000; + if ( f_fStoreFlag == FALSE ) + aulCpuLsuCmd[0] |= 0xC0000000; /* EGO load. */ + else + aulCpuLsuCmd[0] |= 0xE0000000; /* EGO store. */ + + aulCpuLsuCmd[0] |= (f_ulNumEntry - 1) << 19; + aulCpuLsuCmd[0] |= cOCT6100_PART1_API_SCRATCH_PAD; + + /* Create DWORD 1 of command. */ + aulCpuLsuCmd[1] = 0x00000000; + aulCpuLsuCmd[1] |= ( ( cOCT6100_PART1_API_SCRATCH_PAD + 0x10 ) & 0xFFFF ) << 16; + aulCpuLsuCmd[1] |= pSharedInfo->MiscVars.usCodepoint; + + /* Write the EGO command in the LSU CB. */ + WriteParams.ulWriteAddress = cOCT6100_PART1_CPU_LSU_CB_BASE + ((pSharedInfo->MiscVars.usCpuLsuWritePtr & 0x7) * 0x8 ); + WriteParams.usWriteData = (UINT16)(( aulCpuLsuCmd[ 0 ] >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( aulCpuLsuCmd[ 0 ] & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)(( aulCpuLsuCmd[ 1 ] >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( aulCpuLsuCmd[ 1 ] & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Post increment the write pointer. */ + pSharedInfo->MiscVars.usCpuLsuWritePtr++; + + /* Indicate new write pointer position to HW. */ + WriteParams.ulWriteAddress = cOCT6100_PART1_EGO_REG + 0x5A; + WriteParams.usWriteData = (UINT16)( pSharedInfo->MiscVars.usCpuLsuWritePtr & 0x7 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for codepoint to be updated before returning. */ + while( fConditionFlag ) + { + ReadParams.ulReadAddress = cOCT6100_PART1_API_SCRATCH_PAD + 0x12; + usReadData = (UINT16)( pSharedInfo->MiscVars.usCodepoint ); + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData == pSharedInfo->MiscVars.usCodepoint ) + fConditionFlag = FALSE; + + ulLoopCounter++; + + if ( ulLoopCounter == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_OPEN_EGO_TIMEOUT; + } + + /* CRC error bit must be zero. */ + ReadParams.ulReadAddress = 0x202; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( ( usReadData & 0x0400 ) != 0 ) + return cOCT6100_ERR_OPEN_CORRUPTED_IMAGE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCreateEgoEntry + +Description: Private function used to create an access structure to be sent + to the internal processors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_ulExternalAddress External memory address for the access. +f_ulInternalAddress Which process should receive the command. +f_ulNumBytes Number of bytes associated to the access. +f_aulEntry Array of access to perform. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCreateEgoEntry +UINT32 Oct6100ApiCreateEgoEntry( + IN UINT32 f_ulExternalAddress, + IN UINT32 f_ulInternalAddress, + IN UINT32 f_ulNumBytes, + OUT UINT32 f_aulEntry[ 2 ] ) +{ + f_aulEntry[0] = 0x80000000; + f_aulEntry[0] |= f_ulExternalAddress & 0x07FFFFFC; + + f_aulEntry[1] = 0x0011C000; + f_aulEntry[1] |= (f_ulNumBytes / 8) << 23; + f_aulEntry[1] |= (f_ulInternalAddress >> 2) & 0x3FFF; + + return cOCT6100_ERR_OK; +} +#endif + + + + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitChannels + +Description: This function will initialize all the channels to power down. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInitChannels +UINT32 Oct6100ApiInitChannels( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 i; + UINT32 ulResult; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT16 usReadData; + UINT32 ulTempData; + UINT32 ulBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulMask; + UINT16 usLoopCount = 0; + UINT16 usWriteData = 0; + UINT16 usMclkRead; + UINT16 usLastMclkRead; + UINT16 usMclkDiff; + UINT32 ulNumberOfCycleToWait; + UINT32 ulTimeoutCounter; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Verify that the image has enough memory to work correctly. */ + if ( ( pSharedInfo->MiscVars.ulTotalMemSize + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) < pSharedInfo->MemoryMap.ulFreeMemBaseAddress ) + return cOCT6100_ERR_OPEN_INSUFFICIENT_EXTERNAL_MEMORY; + + /* Verify that the tail length is supported by the device.*/ + if ( pSharedInfo->ChipConfig.usTailDisplacement > pSharedInfo->ImageInfo.usMaxTailDisplacement ) + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_TAIL_DISPLACEMENT_VALUE; + + /* Verify that acoustic echo is supported by the device. */ + if ( pSharedInfo->ChipConfig.fEnableAcousticEcho == TRUE && pSharedInfo->ImageInfo.fAcousticEcho == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_ACOUSTIC_ECHO; + + /* Verify that the image supports all the requested channels. */ + if ( pSharedInfo->ChipConfig.usMaxChannels > pSharedInfo->ImageInfo.usMaxNumberOfChannels ) + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_MAX_ECHO_CHANNELS_VALUE; + + /* Max number of channels the image supports + 1 for channel recording, if requested */ + if ( ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + && ( pSharedInfo->ImageInfo.usMaxNumberOfChannels < cOCT6100_MAX_ECHO_CHANNELS ) + && ( pSharedInfo->ChipConfig.usMaxChannels == pSharedInfo->ImageInfo.usMaxNumberOfChannels ) ) + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_MAX_ECHO_CHANNELS_VALUE; + + /* Initialize the memory for all required channels. */ + for( i = 0; i < f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels; i++ ) + { + /*==============================================================================*/ + /* Configure the Global Static Configuration memory of the channel. */ + + ulBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( i * cOCT6100_CHANNEL_ROOT_SIZE ) + cOCT6100_CHANNEL_ROOT_GLOBAL_CONF_OFFSET; + + /* Set the PGSP context base address. */ + ulTempData = pSharedInfo->MemoryMap.ulChanMainMemBase + ( i * pSharedInfo->MemoryMap.ulChanMainMemSize ) + cOCT6100_CH_MAIN_PGSP_CONTEXT_OFFSET; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_PGSP_CONTEXT_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the PGSP init context base address. */ + ulTempData = ( cOCT6100_IMAGE_FILE_BASE + 0x200 ) & 0x07FFFFFF; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_PGSP_INIT_CONTEXT_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the RIN circular buffer base address. */ + ulTempData = pSharedInfo->MemoryMap.ulChanMainMemBase + ( i * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainRinCBMemOfst; + + /* Set the circular buffer size. */ + ulTempData &= 0xFFFFFF00; + if (( pSharedInfo->MemoryMap.ulChanMainRinCBMemSize & 0xFFFF00FF ) != 0 ) + return cOCT6100_ERR_CHANNEL_INVALID_RIN_CB_SIZE; + ulTempData |= pSharedInfo->MemoryMap.ulChanMainRinCBMemSize >> 8; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_RIN_CIRC_BUFFER_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the SIN circular buffer base address. */ + ulTempData = pSharedInfo->MemoryMap.ulChanMainMemBase + ( i * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainSinCBMemOfst; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_SIN_CIRC_BUFFER_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the SOUT circular buffer base address. */ + ulTempData = pSharedInfo->MemoryMap.ulChanMainMemBase + ( i * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainSoutCBMemOfst;; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_SOUT_CIRC_BUFFER_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + } + + /* Put all channel in powerdown mode "3". */ + for( i = 0; i < f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels; i++ ) + { + WriteParams.ulWriteAddress = 0x014000 + (i*4) + 0; + WriteParams.usWriteData = 0x85FF; /* TSI index 1535 reserved for power-down mode */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x014000 + (i*4) + 2; + WriteParams.usWriteData = 0xC5FF; /* TSI index 1535 reserved for power-down mode */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Set the maximum number of channels. */ + WriteParams.ulWriteAddress = 0x690; + if ( pSharedInfo->ImageInfo.usMaxNumberOfChannels < 384 ) + WriteParams.usWriteData = 384; + else + WriteParams.usWriteData = (UINT16)pSharedInfo->ImageInfo.usMaxNumberOfChannels; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set power-dowm TSI chariot memory to silence. */ + for( i = 0; i < 6; i++ ) + { + WriteParams.ulWriteAddress = 0x20000 + ( i * 0x1000 ) + ( 1534 * 2 ); + WriteParams.usWriteData = 0x3EFF; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x20000 + ( i * 0x1000 ) + ( 1535 * 2 ); + WriteParams.usWriteData = 0x3EFF; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Remove chariot hold. */ + WriteParams.ulWriteAddress = 0x500; + WriteParams.usWriteData = 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + for( usLoopCount = 0; usLoopCount < 4096; usLoopCount++ ) + { + if ( (usLoopCount % 16) < 8 ) + { + usWriteData = (UINT16)((usLoopCount / 16) << 7); + usWriteData |= (UINT16)((usLoopCount % 8)); + } + else + { + usWriteData = (UINT16)((usLoopCount / 16) << 7); + usWriteData |= (UINT16)((usLoopCount % 8)); + usWriteData |= 0x78; + } + + /* Set timeslot pointer. */ + WriteParams.ulWriteAddress = 0x50E; + WriteParams.usWriteData = 0x0003; + WriteParams.usWriteData |= usWriteData << 2; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now read the mclk counter. */ + ReadParams.ulReadAddress = 0x30A; + ReadParams.pusReadData = &usLastMclkRead; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reset loop timeout counter. */ + ulTimeoutCounter = 0x0; + + do { + ReadParams.pusReadData = &usMclkRead; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( ( usLoopCount % 16 ) != 15 ) + { + ulNumberOfCycleToWait = 133; + } + else + { + ulNumberOfCycleToWait = 20000; + } + + /* Evaluate the difference. */ + usMclkDiff = (UINT16)(( usMclkRead - usLastMclkRead ) & 0xFFFF); + + /* Check for loop timeout. Bad mclk? */ + ulTimeoutCounter++; + if ( ulTimeoutCounter == cOCT6100_MAX_LOOP_CPU_TIMEOUT ) + return cOCT6100_ERR_FATAL_EA; + + } while( usMclkDiff <= ulNumberOfCycleToWait ); + } + + /* Back to normal mode. */ + WriteParams.ulWriteAddress = 0x50E; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check for CRC errors. */ + ReadParams.pusReadData = &usReadData; + ReadParams.ulReadAddress = 0x202; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( (usReadData & 0x400) != 0x0000 ) + return cOCT6100_ERR_OPEN_CRC_ERROR; + + /* Clear the error rol raised by manually moving the clocks. */ + WriteParams.ulWriteAddress = 0x502; + WriteParams.usWriteData = 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*======================================================================*/ + /* Write the tail displacement value in external memory. */ + + ulFeatureBytesOffset = pSharedInfo->MemoryMap.PouchTailDisplOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.PouchTailDisplOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.PouchTailDisplOfst.byFieldSize; + + ulResult = Oct6100ApiReadDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + &ulTempData ); + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set the tail displacement. */ + ulTempData |= (pSharedInfo->ChipConfig.usTailDisplacement << ulFeatureBitOffset ); + + /* Write the DWORD where the field is located. */ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*======================================================================*/ + + + /*======================================================================*/ + /* Clear the pouch counter, if present. */ + + if ( pSharedInfo->DebugInfo.fPouchCounter == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.PouchCounterFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.PouchCounterFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.PouchCounterFieldOfst.byFieldSize; + + ulResult = Oct6100ApiReadDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + &ulTempData ); + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + /* Clear counter! */ + ulTempData &= (~ulMask); + + /* Write the DWORD where the field is located.*/ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* The ISR has not yet been called. Set the appropriate bit in external memory. */ + if ( pSharedInfo->DebugInfo.fIsIsrCalledField == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.IsIsrCalledFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.IsIsrCalledFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.IsIsrCalledFieldOfst.byFieldSize; + + ulResult = Oct6100ApiReadDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + &ulTempData ); + + /* Read previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + /* Toggle the bit to '1'. */ + ulTempData |= 1 << ulFeatureBitOffset; + + /* Write the DWORD where the field is located.*/ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitToneInfo + +Description: This function will parse the software image and retrieve + the information about the tones that it supports. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInitToneInfo +UINT32 Oct6100ApiInitToneInfo( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + UINT32 ulResult; + + unsigned char const *pszToneInfoStart = NULL; + unsigned char const *pszToneInfoEnd = NULL; + + unsigned char const *pszCurrentInfo; + unsigned char const *pszNextInfo; + + UINT32 ulToneEventNumber; + UINT32 ulTempValue; + UINT32 ulNumCharForValue; + UINT32 ulUniqueToneId; + UINT32 ulToneNameSize; + UINT32 ulOffset = 0; + + UINT32 i; + + /* Init the tone detector parameter. */ + f_pApiInstance->pSharedInfo->ImageInfo.byNumToneDetectors = 0; + + /* Find the start and the end of the tone info section. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize > 4096 ) + { + /* For performance reasons, and since the tone detector information */ + /* is always located at the end of the image file, try to start from the end */ + /* of the buffer. */ + + ulOffset = f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize - 2048; + pszToneInfoStart = Oct6100ApiStrStr( f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + ulOffset, + (PUINT8)cOCT6100_TONE_INFO_START_STRING, + f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize ); + + /* Check if the information was found. */ + if ( pszToneInfoStart == NULL ) + { + /* Try again, but giving a larger string to search. */ + ulOffset = f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize - 4096; + pszToneInfoStart = Oct6100ApiStrStr( f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + ulOffset, + (PUINT8)cOCT6100_TONE_INFO_START_STRING, + f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize ); + + } + } + + if ( pszToneInfoStart == NULL ) + { + /* Travel through the whole file buffer. */ + pszToneInfoStart = Oct6100ApiStrStr( f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile, + (PUINT8)cOCT6100_TONE_INFO_START_STRING, + f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize ); + } + /* We have to return immediatly if no tones are found. */ + if ( pszToneInfoStart == NULL ) + return cOCT6100_ERR_OK; + + /* The end of the tone detector information is after the beginning of the tone information. */ + pszToneInfoEnd = Oct6100ApiStrStr( pszToneInfoStart, + (PUINT8)cOCT6100_TONE_INFO_STOP_STRING, + f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize ); + if ( pszToneInfoEnd == NULL ) + return cOCT6100_ERR_OPEN_TONE_INFO_STOP_TAG_NOT_FOUND; + + /* Find and process all tone events within the region. */ + pszCurrentInfo = Oct6100ApiStrStr( pszToneInfoStart, (PUINT8)cOCT6100_TONE_INFO_EVENT_STRING, pszToneInfoEnd ); + + while ( pszCurrentInfo != NULL ) + { + /* Skip the string. */ + pszCurrentInfo += ( Oct6100ApiStrLen( (PUINT8)cOCT6100_TONE_INFO_EVENT_STRING ) ); + + /* Extract the number of char used to represent the tone event number ( 1 or 2 ). */ + pszNextInfo = Oct6100ApiStrStr( pszCurrentInfo, (PUINT8)",", pszToneInfoEnd ); + ulNumCharForValue = (UINT32)( pszNextInfo - pszCurrentInfo ); + + /* Retreive the event number */ + ulToneEventNumber = 0; + for ( i = ulNumCharForValue; i > 0; i-- ) + { + ulResult = Oct6100ApiAsciiToHex( *pszCurrentInfo, &ulTempValue ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulToneEventNumber |= ( ulTempValue << (( i - 1) * 4 ) ); + pszCurrentInfo++; + } + + if ( ulToneEventNumber >= cOCT6100_MAX_TONE_EVENT ) + return cOCT6100_ERR_OPEN_INVALID_TONE_EVENT; + + /* Skip the comma and the 0x. */ + pszCurrentInfo += 3; + + /*======================================================================*/ + /* Retreive the unique tone id. */ + ulUniqueToneId = 0; + for ( i = 0; i < 8; i++ ) + { + ulResult = Oct6100ApiAsciiToHex( *pszCurrentInfo, &ulTempValue ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulOffset = 28 - ( i * 4 ); + ulUniqueToneId |= ( ulTempValue << ulOffset ); + pszCurrentInfo++; + } + + /*======================================================================*/ + + /* Skip the comma. */ + pszCurrentInfo++; + + /* Find out where the next event info starts */ + pszNextInfo = Oct6100ApiStrStr( pszCurrentInfo,(PUINT8) cOCT6100_TONE_INFO_EVENT_STRING, pszToneInfoEnd ); + if ( pszNextInfo == NULL ) + pszNextInfo = pszToneInfoEnd; + + /* Extract the name size. */ + ulToneNameSize = (UINT32)( pszNextInfo - pszCurrentInfo - 2 ); /* - 2 for 0x0D and 0x0A.*/ + + if ( ulToneNameSize > cOCT6100_TLV_MAX_TONE_NAME_SIZE ) + return cOCT6100_ERR_OPEN_INVALID_TONE_NAME; + + /* Copy the tone name into the image info structure. */ + ulResult = Oct6100UserMemCopy( f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].aszToneName, + pszCurrentInfo, + ulToneNameSize ); + + + + /* Update the tone info into the image info structure. */ + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulToneID = ulUniqueToneId; + /* Find out the port on which this tone detector is associated. */ + switch( (ulUniqueToneId >> 28) & 0xF ) + { + case 1: + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulDetectionPort = cOCT6100_CHANNEL_PORT_ROUT; + break; + + case 2: + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulDetectionPort = cOCT6100_CHANNEL_PORT_SIN; + break; + + case 4: + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulDetectionPort = cOCT6100_CHANNEL_PORT_SOUT; + break; + + case 5: + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulDetectionPort = cOCT6100_CHANNEL_PORT_ROUT_SOUT; + break; + + default: + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulDetectionPort = cOCT6100_INVALID_PORT; + break; + } + + /* Find out where the next event info starts */ + pszNextInfo = Oct6100ApiStrStr( pszCurrentInfo,(PUINT8) cOCT6100_TONE_INFO_EVENT_STRING, pszToneInfoEnd ); + /* Update the current info pointer. */ + pszCurrentInfo = pszNextInfo; + + f_pApiInstance->pSharedInfo->ImageInfo.byNumToneDetectors++; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiExternalMemoryBist + +Description: Tests the functionality of the external memories. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiExternalMemoryBist +UINT32 Oct6100ApiExternalMemoryBist( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulMemSize = 0; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Test the external memory. */ + switch ( pSharedInfo->ChipConfig.ulMemoryChipSize ) + { + case cOCT6100_MEMORY_CHIP_SIZE_8MB: + ulMemSize = cOCT6100_SIZE_8M; + break; + case cOCT6100_MEMORY_CHIP_SIZE_16MB: + ulMemSize = cOCT6100_SIZE_16M; + break; + case cOCT6100_MEMORY_CHIP_SIZE_32MB: + ulMemSize = cOCT6100_SIZE_32M; + break; + case cOCT6100_MEMORY_CHIP_SIZE_64MB: + ulMemSize = cOCT6100_SIZE_64M; + break; + case cOCT6100_MEMORY_CHIP_SIZE_128MB: + ulMemSize = cOCT6100_SIZE_128M; + break; + default: + return cOCT6100_ERR_FATAL_D9; + } + + ulMemSize *= pSharedInfo->ChipConfig.byNumMemoryChips; + + ulResult = Oct6100ApiRandomMemoryWrite( f_pApiInstance, cOCT6100_EXTERNAL_MEM_BASE_ADDRESS, ulMemSize, 16, 1000, cOCT6100_ERR_OPEN_EXTERNAL_MEM_BIST_FAILED ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Make sure the user I/O functions are working as required. */ + ulResult = Oct6100ApiUserIoTest( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGenerateNumber + +Description: Generate a number using an index. Passing the same + index generates the same number. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_ulIndex Index used to generate the random number. +f_ulDataMask Data mask to apply to generated number. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGenerateNumber +UINT16 Oct6100ApiGenerateNumber( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulIndex, + IN UINT32 f_ulDataMask ) +{ + UINT16 usGeneratedNumber; + + usGeneratedNumber = (UINT16)( ( ( ~( f_ulIndex - 1 ) ) & 0xFF00 ) | ( ( f_ulIndex + 1 ) & 0xFF ) ); + + return (UINT16)( usGeneratedNumber & f_ulDataMask ); +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRandomMemoryWrite + +Description: Writes to f_ulNumAccesses random locations in the indicated + memory and read back to test the operation of that memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_ulMemBase Base address of the memory access. +f_ulMemSize Size of the memory to be tested. +f_ulNumDataBits Number of data bits. +f_ulNumAccesses Number of random access to be perform. +f_ulErrorCode Error code to be returned if the bist fails. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRandomMemoryWrite +UINT32 Oct6100ApiRandomMemoryWrite( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulMemBase, + IN UINT32 f_ulMemSize, + IN UINT32 f_ulNumDataBits, + IN UINT32 f_ulNumAccesses, + IN UINT32 f_ulErrorCode ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulDataMask; + UINT32 ulResult, i, j; + UINT32 ulBistAddress; + UINT16 usReadData; + UINT32 aulBistAddress[20]={0x00000000, 0x00000002, 0x00000004, 0x007FFFFE, + 0x00900000, 0x00900006, 0x00900008, 0x009FFFFE, + 0x01000000, 0x0100000A, 0x0200000C, 0x01FFFFFE, + 0x03000000, 0x03000002, 0x04000004, 0x03FFFFFE, + 0x04000000, 0x05000006, 0x06000008, 0x07FFFFFE}; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Determine mask for number of data bits. */ + ulDataMask = (1 << f_ulNumDataBits) - 1; + + /* Write specific data to specific address */ + WriteParams.ulWriteAddress = f_ulMemBase | 0x00001000; + WriteParams.usWriteData = 0xCAFE; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + for(j=0; j<20; j++) + { + /* Change address to test lower and higher part of the 32 bit bus */ + ulBistAddress = aulBistAddress[j]; + ulBistAddress &= f_ulMemSize - 2; + ulBistAddress |= f_ulMemBase; + + /* Bist 16 data pins of this address */ + for ( i = 0; i < 16; i ++) + { + WriteParams.ulWriteAddress = ulBistAddress; + WriteParams.usWriteData = (UINT16)(0x1 << i); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Read back the specific data to flush the data bus.*/ + ReadParams.ulReadAddress = f_ulMemBase | 0x00001000; + ReadParams.pusReadData = &usReadData; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != 0xCAFE ) + return f_ulErrorCode; + + /* Read back the data written.*/ + ReadParams.ulReadAddress = WriteParams.ulWriteAddress; + ReadParams.pusReadData = &usReadData; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != (UINT16)(0x1 << i) ) + return f_ulErrorCode; + } + } + + /* Perform the first write at address 0 + mem base */ + j = 0; + WriteParams.ulWriteAddress = f_ulMemBase; + WriteParams.usWriteData = Oct6100ApiGenerateNumber( f_pApiInstance, j, ulDataMask ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Try each address line of the memory. */ + for ( i = 2, j = 1; i < f_ulMemSize; i <<= 1, j++ ) + { + WriteParams.ulWriteAddress = ( f_ulMemBase + i ); + WriteParams.usWriteData = Oct6100ApiGenerateNumber( f_pApiInstance, j, ulDataMask ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + for ( i = 0; i < j; i++ ) + { + if ( i > 0 ) + ReadParams.ulReadAddress = ( f_ulMemBase + ( 0x1 << i ) ); + else + ReadParams.ulReadAddress = f_ulMemBase; + ReadParams.pusReadData = &usReadData; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != Oct6100ApiGenerateNumber( f_pApiInstance, i, ulDataMask ) ) + return f_ulErrorCode; + } + + /* Write to random addresses of the memory. */ + for ( i = 0; i < f_ulNumAccesses; i++ ) + { + ulBistAddress = (UINT16)Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ) << 16; + ulBistAddress |= (UINT16)Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ); + ulBistAddress &= f_ulMemSize - 2; + ulBistAddress |= f_ulMemBase; + + WriteParams.ulWriteAddress = ulBistAddress; + WriteParams.usWriteData = Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + for ( i = 0; i < f_ulNumAccesses; i++ ) + { + ulBistAddress = (UINT16)Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ) << 16; + ulBistAddress |= (UINT16)Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ); + ulBistAddress &= f_ulMemSize - 2; + ulBistAddress |= f_ulMemBase; + + ReadParams.ulReadAddress = ulBistAddress; + ReadParams.pusReadData = &usReadData; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( ( usReadData & ulDataMask ) != ( Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ) & ulDataMask ) ) + return f_ulErrorCode; + } + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUserIoTest + +Description: This function will verify the correct functionality of + the following user functions: + + - Oct6100UserDriverWriteBurstApi + - Oct6100UserDriverWriteSmearApi + - Oct6100UserDriverReadBurstApi + + The Oct6100UserDriverWriteApi and Oct6100UserDriverReadApi + functions do not need to be tested here as this has be done in + the external memory bisting function above. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUserIoTest +UINT32 Oct6100ApiUserIoTest( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_BURST_PARAMS WriteBurstParams; + tOCT6100_WRITE_SMEAR_PARAMS WriteSmearParams; + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_READ_BURST_PARAMS ReadBurstParams; + UINT32 ulResult, i; + UINT16 usReadData; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteBurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteBurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + /* Test what the user has specified is the maximum that can be used for a burst. */ + WriteBurstParams.ulWriteLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + WriteBurstParams.pusWriteData = pSharedInfo->MiscVars.ausSuperArray; + + WriteSmearParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteSmearParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + /* Test what the user has specified is the maximum that can be used for a smear. */ + WriteSmearParams.ulWriteLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + ReadBurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadBurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + /* Test what the user has specified is the maximum that can be used for a burst. */ + ReadBurstParams.ulReadLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + ReadBurstParams.pusReadData = pSharedInfo->MiscVars.ausSuperArray; + + + /*======================================================================*/ + /* Write burst check. */ + + WriteBurstParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + /* Set the random data to be written. */ + for ( i = 0; i < WriteBurstParams.ulWriteLength; i++ ) + { + WriteBurstParams.pusWriteData[ i ] = Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ); + } + mOCT6100_DRIVER_WRITE_BURST_API( WriteBurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Read back pattern using simple read function and make sure we are reading what's expected. */ + ReadParams.ulReadAddress = WriteBurstParams.ulWriteAddress; + for ( i = 0; i < WriteBurstParams.ulWriteLength; i++ ) + { + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the data matches. */ + if ( usReadData != WriteBurstParams.pusWriteData[ i ] ) + { + /* The values do not match. Something seems to be wrong with the WriteBurst user function. */ + return cOCT6100_ERR_OPEN_USER_WRITE_BURST_FAILED; + } + + /* Next address to check. */ + ReadParams.ulReadAddress += 2; + } + + /*======================================================================*/ + + + /*======================================================================*/ + /* Write smear check. */ + + WriteSmearParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + ( WriteBurstParams.ulWriteLength * 2 ); + /* Set the random data to be written. */ + WriteSmearParams.usWriteData = Oct6100ApiGenerateNumber( f_pApiInstance, Oct6100ApiRand( 0xFFFF ), 0xFFFF ); + mOCT6100_DRIVER_WRITE_SMEAR_API( WriteSmearParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Read back pattern using simple read function and make sure we are reading what's expected. */ + ReadParams.ulReadAddress = WriteSmearParams.ulWriteAddress; + for ( i = 0; i < WriteSmearParams.ulWriteLength; i++ ) + { + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the data matches. */ + if ( usReadData != WriteSmearParams.usWriteData ) + { + /* The values do not match. Something seems to be wrong with the WriteSmear user function. */ + return cOCT6100_ERR_OPEN_USER_WRITE_SMEAR_FAILED; + } + + /* Next address to check. */ + ReadParams.ulReadAddress += 2; + } + + /*======================================================================*/ + + + /*======================================================================*/ + /* Read burst check. */ + + /* First check with what the WriteBurst function wrote. */ + ReadBurstParams.ulReadAddress = WriteBurstParams.ulWriteAddress; + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + for ( i = 0; i < ReadBurstParams.ulReadLength; i++ ) + { + /* Check if the data matches. */ + if ( ReadBurstParams.pusReadData[ i ] != Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ) ) + { + /* The values do not match. Something seems to be wrong with the ReadBurst user function. */ + return cOCT6100_ERR_OPEN_USER_READ_BURST_FAILED; + } + } + + /* Then check with what the WriteSmear function wrote. */ + ReadBurstParams.ulReadAddress = WriteSmearParams.ulWriteAddress; + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + for ( i = 0; i < ReadBurstParams.ulReadLength; i++ ) + { + /* Check if the data matches. */ + if ( ReadBurstParams.pusReadData[ i ] != WriteSmearParams.usWriteData ) + { + /* The values do not match. Something seems to be wrong with the ReadBurst user function. */ + return cOCT6100_ERR_OPEN_USER_READ_BURST_FAILED; + } + } + + /*======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiExternalMemoryInit + +Description: Initialize the external memory before uploading the image. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiExternalMemoryInit +UINT32 Oct6100ApiExternalMemoryInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_SMEAR_PARAMS SmearParams; + UINT32 ulTotalWordToWrite; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + SmearParams.pProcessContext = f_pApiInstance->pProcessContext; + + SmearParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Clear the first part of the memory. */ + ulTotalWordToWrite = 0x400; + SmearParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + + while ( ulTotalWordToWrite != 0 ) + { + if ( ulTotalWordToWrite >= pSharedInfo->ChipConfig.usMaxRwAccesses ) + SmearParams.ulWriteLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + else + SmearParams.ulWriteLength = ulTotalWordToWrite; + + SmearParams.usWriteData = 0x0; + + mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the number of words to write. */ + ulTotalWordToWrite -= SmearParams.ulWriteLength; + /* Update the address. */ + SmearParams.ulWriteAddress += ( SmearParams.ulWriteLength * 2 ); + } + + /* Clear the TLV flag.*/ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, cOCT6100_TLV_BASE, 0x0 ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitMixer + +Description: This function will initialize the mixer memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInitMixer +UINT32 Oct6100ApiInitMixer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_BURST_PARAMS BurstParams; + UINT16 ausWriteData[ 4 ]; + UINT32 ulResult; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + BurstParams.pusWriteData = ausWriteData; + /*======================================================================*/ + /* Initialize the mixer memory if required. */ + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + { + /* Modify the mixer pointer by adding the record event into the link list. */ + pSharedInfo->MixerInfo.usFirstSinCopyEventPtr = pSharedInfo->MixerInfo.usRecordSinEventIndex; + pSharedInfo->MixerInfo.usLastSinCopyEventPtr = pSharedInfo->MixerInfo.usRecordSinEventIndex; + pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr = pSharedInfo->MixerInfo.usRecordCopyEventIndex; + pSharedInfo->MixerInfo.usLastSoutCopyEventPtr = pSharedInfo->MixerInfo.usRecordCopyEventIndex; + + /* Program the Sin copy event. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSharedInfo->MixerInfo.usRecordSinEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + BurstParams.ulWriteLength = 4; + + ausWriteData[ 0 ] = 0x0000; + ausWriteData[ 1 ] = 0x0000; + ausWriteData[ 2 ] = (UINT16)(cOCT6100_MIXER_TAIL_NODE & 0x7FF); /* Head node.*/ + ausWriteData[ 3 ] = 0x0000; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Program the Sout copy event. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSharedInfo->MixerInfo.usRecordCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + BurstParams.ulWriteLength = 4; + + ausWriteData[ 0 ] = 0x0000; + ausWriteData[ 1 ] = 0x0000; + ausWriteData[ 2 ] = (UINT16)(pSharedInfo->MixerInfo.usRecordSinEventIndex & 0x7FF); + ausWriteData[ 3 ] = 0x0000; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the head node. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE; + BurstParams.ulWriteLength = 4; + + ausWriteData[ 0 ] = 0x0000; + ausWriteData[ 1 ] = 0x0000; + ausWriteData[ 2 ] = (UINT16)(pSharedInfo->MixerInfo.usRecordCopyEventIndex & 0x7FF); + ausWriteData[ 3 ] = 0x0000; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Init the mixer pointer */ + pSharedInfo->MixerInfo.usFirstSinCopyEventPtr = pSharedInfo->MixerInfo.usRecordSinEventIndex; + } + else + { + /* Configure the head node. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE; + BurstParams.ulWriteLength = 4; + + ausWriteData[ 0 ] = 0x0000; + ausWriteData[ 1 ] = 0x0000; + ausWriteData[ 2 ] = (UINT16)(cOCT6100_MIXER_TAIL_NODE & 0x7FF); /* Head node. */ + ausWriteData[ 3 ] = 0x0000; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the tail node. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + 0x10; + BurstParams.ulWriteLength = 4; + + ausWriteData[ 0 ] = 0x0000; + ausWriteData[ 1 ] = 0x0000; + ausWriteData[ 2 ] = (UINT16)(cOCT6100_MIXER_HEAD_NODE & 0x7FF); /* Head node. */ + ausWriteData[ 3 ] = 0x0000; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitRecordResources + +Description: This function will initialize the resources required to + perform recording on a debug channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInitRecordResources +UINT32 Oct6100ApiInitRecordResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check if recording is enabled. */ + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == FALSE ) + return cOCT6100_ERR_OK; + + if ( pSharedInfo->DebugInfo.usRecordMemIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_DEBUG_RECORD; + + /* Check the provided recording memory index within the SSPX. */ + if ( pSharedInfo->DebugInfo.usRecordMemIndex != ( pSharedInfo->ImageInfo.usMaxNumberOfChannels - 1 ) ) + return cOCT6100_ERR_OPEN_DEBUG_MEM_INDEX; + + /* Reserve the TSI entries for the channel. */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, &pSharedInfo->DebugInfo.usRecordRinRoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, &pSharedInfo->DebugInfo.usRecordSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Open the debug channel. */ + ulResult = Oct6100ApiDebugChannelOpen( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100FreeResourcesSer + +Description: This function closes all opened channels and frees all + specified global resources used by the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pFreeResources Pointer to user structure in which to choose what + to free. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100FreeResourcesSer +UINT32 Oct6100FreeResourcesSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_FREE_RESOURCES f_pFreeResources ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + + UINT32 ulResult; + UINT32 i; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Close all bidirectional channels. */ + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxBiDirChannels; i ++ ) + { + tPOCT6100_API_BIDIR_CHANNEL pBiDirChanEntry; + + mOCT6100_GET_BIDIR_CHANNEL_ENTRY_PNT( pSharedInfo, pBiDirChanEntry, i ); + + if ( pBiDirChanEntry->fReserved == TRUE ) + { + tOCT6100_CHANNEL_DESTROY_BIDIR DestroyBidir; + + Oct6100ChannelDestroyBiDirDef( &DestroyBidir ); + + DestroyBidir.ulBiDirChannelHndl = cOCT6100_HNDL_TAG_BIDIR_CHANNEL | (pBiDirChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + ulResult = Oct6100ChannelDestroyBiDirSer( f_pApiInstance, &DestroyBidir ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Close all bridge participants. */ + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxChannels; i ++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, i ); + if ( pChanEntry->fReserved == TRUE && pChanEntry->usBridgeIndex != cOCT6100_INVALID_INDEX ) + { + /* This channel is on a bridge. */ + tOCT6100_CONF_BRIDGE_CHAN_REMOVE BridgeChanRemove; + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + + Oct6100ConfBridgeChanRemoveDef( &BridgeChanRemove ); + + /* Obtain a pointer to the conference bridge's list entry. */ + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, pChanEntry->usBridgeIndex ); + + BridgeChanRemove.fRemoveAll = TRUE; + BridgeChanRemove.ulConfBridgeHndl = cOCT6100_HNDL_TAG_CONF_BRIDGE | (pBridgeEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | pChanEntry->usBridgeIndex; + + ulResult = Oct6100ConfBridgeChanRemoveSer( f_pApiInstance, &BridgeChanRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Close all opened channels. This will bring the broadcast TSSTs with it. */ + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxChannels; i ++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, i ); + + if ( pChanEntry->fReserved == TRUE ) + { + tOCT6100_CHANNEL_CLOSE ChannelClose; + + /* Generate handle. */ + ChannelClose.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | (pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + /* Call serialized close channel function. */ + ulResult = Oct6100ChannelCloseSer( f_pApiInstance, &ChannelClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /* Close all TSI connections. */ + if ( f_pFreeResources->fFreeTsiConnections == TRUE ) + { + tPOCT6100_API_TSI_CNCT pTsiCnct; + tOCT6100_TSI_CNCT_CLOSE TsiCnctClose; + + Oct6100TsiCnctCloseDef( &TsiCnctClose ); + + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxTsiCncts; i ++ ) + { + /* Obtain a pointer to the TSI connection list entry. */ + mOCT6100_GET_TSI_CNCT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsiCnct, i ); + + if ( pTsiCnct->fReserved == TRUE ) + { + TsiCnctClose.ulTsiCnctHndl = cOCT6100_HNDL_TAG_TSI_CNCT | (pTsiCnct->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + ulResult = Oct6100TsiCnctCloseSer( f_pApiInstance, &TsiCnctClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + /* Close all conference bridges. */ + if ( f_pFreeResources->fFreeConferenceBridges == TRUE ) + { + tPOCT6100_API_CONF_BRIDGE pConfBridge; + tOCT6100_CONF_BRIDGE_CLOSE ConfBridgeClose; + + Oct6100ConfBridgeCloseDef( &ConfBridgeClose ); + + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxConfBridges; i ++ ) + { + /* Obtain a pointer to the conference bridge's list entry. */ + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pConfBridge, i ); + + if ( pConfBridge->fReserved == TRUE ) + { + ConfBridgeClose.ulConfBridgeHndl = cOCT6100_HNDL_TAG_CONF_BRIDGE | (pConfBridge->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + ulResult = Oct6100ConfBridgeCloseSer( f_pApiInstance, &ConfBridgeClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Free all playout buffers loaded in external memory. */ + if ( f_pFreeResources->fFreePlayoutBuffers == TRUE ) + { + tPOCT6100_API_BUFFER pBuffer; + tOCT6100_BUFFER_UNLOAD BufferUnload; + + Oct6100BufferPlayoutUnloadDef( &BufferUnload ); + + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxPlayoutBuffers; i ++ ) + { + + + /* Obtain a pointer to the buffer list entry. */ + mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBuffer, i ); + + if ( pBuffer->fReserved == TRUE ) + { + BufferUnload.ulBufferIndex = i; + ulResult = Oct6100BufferUnloadSer( f_pApiInstance, &BufferUnload, TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Close all phasing TSSTs. */ + if ( f_pFreeResources->fFreePhasingTssts == TRUE ) + { + tPOCT6100_API_PHASING_TSST pPhasingTsst; + tOCT6100_PHASING_TSST_CLOSE PhasingTsstClose; + + Oct6100PhasingTsstCloseDef( &PhasingTsstClose ); + + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxPhasingTssts; i ++ ) + { + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( pSharedInfo, pPhasingTsst, i ); + + if ( pPhasingTsst->fReserved == TRUE ) + { + PhasingTsstClose.ulPhasingTsstHndl = cOCT6100_HNDL_TAG_PHASING_TSST | (pPhasingTsst->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + ulResult = Oct6100PhasingTsstCloseSer( f_pApiInstance, &PhasingTsstClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + /* Close all ADPCM channels. */ + if ( f_pFreeResources->fFreeAdpcmChannels == TRUE ) + { + tPOCT6100_API_ADPCM_CHAN pAdpcmChannel; + tOCT6100_ADPCM_CHAN_CLOSE AdpcmChanClose; + + Oct6100AdpcmChanCloseDef( &AdpcmChanClose ); + + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxAdpcmChannels; i ++ ) + { + mOCT6100_GET_ADPCM_CHAN_ENTRY_PNT( pSharedInfo, pAdpcmChannel, i ); + if ( pAdpcmChannel->fReserved == TRUE ) + { + AdpcmChanClose.ulChanHndl = cOCT6100_HNDL_TAG_ADPCM_CHANNEL | (pAdpcmChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + ulResult = Oct6100AdpcmChanCloseSer( f_pApiInstance, &AdpcmChanClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ProductionBistSer + +Description: This function returns the instantaneous production BIST status. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pProductionBist Pointer to user structure in which BIST status will + be returned. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ProductionBistSer +UINT32 Oct6100ProductionBistSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PRODUCTION_BIST f_pProductionBist ) +{ + UINT32 ulCalculatedCrc = cOCT6100_INVALID_VALUE; + UINT32 ulResult; + UINT32 ulLoopCnt = 0x0; + UINT32 i = 1; + UINT32 ulTotalElements = 4; + UINT32 ulReadAddress = cOCT6100_POUCH_BASE; + UINT32 aulMessage[ 5 ]; + + /* Check if the production bist has been activated. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.fEnableProductionBist == FALSE ) + return cOCT6100_ERR_PRODUCTION_BIST_DISABLED; + + f_pProductionBist->ulCurrentAddress = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulCurrentLoop = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulCurrentTest = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulFailedAddress = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulReadValue = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulExpectedValue = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulBistStatus = cOCT6100_BIST_IN_PROGRESS; + + /* The API knows that the firmware might be writing a status event. */ + /* The firmware does write a status event every 200ms (approximately). */ + /* So the status is read a couple of times to make sure an event was not read while */ + /* it was written. */ + while ( ulLoopCnt != 2 ) + { + /* Read the BIST status in the external memory. */ + for ( i = 0; i < ulTotalElements + 1; i ++ ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, ulReadAddress + i * 4, &aulMessage[ i ] ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Calculate the CRC of this message. */ + ulResult = Oct6100ApiProductionCrc( f_pApiInstance, aulMessage, ulTotalElements, &ulCalculatedCrc ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* If the CRCs do match, break off the while. We have a valid status event. */ + if ( aulMessage[ i - 1 ] == ulCalculatedCrc ) + break; + + ulLoopCnt++; + } + + /* Check if the CRC matches */ + if ( aulMessage[ i - 1 ] != ulCalculatedCrc ) + { + /* Well, the exchange memory at the base of the external memory is corrupted. */ + /* Something very basic is not working correctly with this chip! */ + f_pProductionBist->ulBistStatus = cOCT6100_BIST_STATUS_CRC_FAILED; + } + else + { + /* Check for problems. */ + switch ( aulMessage[ 0 ] & 0xFFFF ) + { + case ( 0x2 ): + + /* The initial configuration failed. */ + f_pProductionBist->ulBistStatus = cOCT6100_BIST_CONFIGURATION_FAILED; + break; + + case ( 0x1 ): + + /* A memory location failed. Return useful information to the user. */ + f_pProductionBist->ulBistStatus = cOCT6100_BIST_MEMORY_FAILED; + + f_pProductionBist->ulFailedAddress = ( aulMessage[ 1 ] & ( ~0x80000000 ) ) + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + f_pProductionBist->ulReadValue = aulMessage[ 2 ]; + f_pProductionBist->ulExpectedValue = aulMessage[ 3 ]; + break; + + case ( 0xFFFF ): + + /* Bist is completed! */ + f_pProductionBist->ulBistStatus = cOCT6100_BIST_SUCCESS; + break; + + default: + /* Bist is in progress. All seems to be working fine up to now. */ + + /* Return progress status. */ + f_pProductionBist->ulCurrentAddress = ( aulMessage[ 1 ] & ( ~0x80000000 ) ) + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + f_pProductionBist->ulCurrentTest = aulMessage[ 2 ]; + f_pProductionBist->ulCurrentLoop = aulMessage[ 3 ]; + break; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiProductionCrc + +Description: This function calculates the crc for a production BIST + message. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pulMessage Message to be exchanged with the firmware. The CRC + will be calculated on this. +f_ulMessageLength Length of the message to be exchanged. This value + does not include the CRC value at the end +f_pulCrcResult Resulting calculated CRC value. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiProductionCrc +UINT32 Oct6100ApiProductionCrc( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN PUINT32 f_pulMessage, + IN UINT32 f_ulMessageLength, + OUT PUINT32 f_pulCrcResult ) +{ + UINT32 ulWidth = 32; + UINT32 ulKey, i, j; + UINT32 ulRemainder = 0; + + /* CRC the message. */ + ulRemainder = f_pulMessage[ f_ulMessageLength - 1 ]; + for ( j = f_ulMessageLength - 1; j != 0xFFFFFFFF ; j-- ) + { + for ( i = 0; i < ulWidth; i++ ) + { + if ( ( ( ulRemainder >> 0x1F ) & 0x1 ) == 0x1 ) + { + /* Division is by something meaningful */ + ulKey = 0x8765DCBA; + } + else + { + /* Remainder is less than our divisor */ + ulKey = 0; + } + ulRemainder = ulRemainder ^ ulKey; + + ulRemainder = ulRemainder << 1; + if ( j != 0 ) + { + ulRemainder = ulRemainder | ( ( f_pulMessage[ j - 1 ] ) >> ( 0x1F - i ) ); + } + } + } + + *f_pulCrcResult = ulRemainder; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiClearInterrupts + +Description: Called only by the Oct6100OpenChip function, this function + writes to all register ROLs to clear them. This is necessary + because some ROLs are set during the startup. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +IN f_pApiInst Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiClearInterrupts +UINT32 Oct6100ApiClearInterrupts( + IN tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + WriteParams.ulWriteAddress = 0x102; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_102H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x202; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_202H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x302; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_302H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x502; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_502H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x702; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_702H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; + +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_stats.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_stats.c new file mode 100644 index 0000000..162c43e --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_stats.c @@ -0,0 +1,441 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_stats.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains functions used to retreive the OCT6100 chip stats. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 89 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_channel_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_chip_stats_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_chip_stats_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_chip_stats_priv.h" + +/**************************** PUBLIC FUNCTIONS *****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChipGetStats + +Description: Retreives the chip statistics and configuration. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChipStats Pointer to a tOCT6100_CHIP_STATS structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChipGetStatsDef +UINT32 Oct6100ChipGetStatsDef( + tPOCT6100_CHIP_STATS f_pChipStats ) +{ + f_pChipStats->fResetChipStats = FALSE; + + f_pChipStats->ulNumberChannels = cOCT6100_INVALID_STAT; + f_pChipStats->ulNumberTsiCncts = cOCT6100_INVALID_STAT; + f_pChipStats->ulNumberConfBridges = cOCT6100_INVALID_STAT; + f_pChipStats->ulNumberPlayoutBuffers = cOCT6100_INVALID_STAT; + f_pChipStats->ulPlayoutFreeMemSize = cOCT6100_INVALID_STAT; + + f_pChipStats->ulNumberPhasingTssts = cOCT6100_INVALID_STAT; + f_pChipStats->ulNumberAdpcmChannels = cOCT6100_INVALID_STAT; + + f_pChipStats->ulH100OutOfSynchCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulH100ClockABadCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulH100FrameABadCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulH100ClockBBadCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulInternalReadTimeoutCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulSdramRefreshTooLateCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulPllJitterErrorCount = cOCT6100_INVALID_STAT; + + f_pChipStats->ulOverflowToneEventsCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulSoftOverflowToneEventsCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulSoftOverflowBufferPlayoutEventsCount = cOCT6100_INVALID_STAT; + + + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ChipGetStats +UINT32 Oct6100ChipGetStats( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CHIP_STATS f_pChipStats ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChipGetStatsSer( f_pApiInstance, f_pChipStats ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChipGetImageInfo + +Description: Retrieves the chip image information indicating the supported + features and tones. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChipImageInfo Pointer to a tPOCT6100_CHIP_IMAGE_INFO structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChipGetImageInfoDef +UINT32 Oct6100ChipGetImageInfoDef( + tPOCT6100_CHIP_IMAGE_INFO f_pChipImageInfo ) +{ + UINT32 i; + + Oct6100UserMemSet( f_pChipImageInfo->szVersionNumber, 0x0, cOCT6100_VERSION_NUMBER_MAX_SIZE ); + + f_pChipImageInfo->fBufferPlayout = FALSE; + f_pChipImageInfo->fAdaptiveNoiseReduction = FALSE; + f_pChipImageInfo->fSoutNoiseBleaching = FALSE; + f_pChipImageInfo->fConferencingNoiseReduction = FALSE; + f_pChipImageInfo->fAutoLevelControl = FALSE; + f_pChipImageInfo->fHighLevelCompensation = FALSE; + f_pChipImageInfo->fSilenceSuppression = FALSE; + + f_pChipImageInfo->fAdpcm = FALSE; + f_pChipImageInfo->fConferencing = FALSE; + f_pChipImageInfo->fDominantSpeaker = FALSE; + f_pChipImageInfo->ulMaxChannels = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulNumTonesAvailable = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulToneProfileNumber = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulMaxTailDisplacement = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulBuildId = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulMaxTailLength = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulDebugEventSize = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulMaxPlayoutEvents = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulImageType = cOCT6100_INVALID_VALUE; + + f_pChipImageInfo->fAcousticEcho = FALSE; + f_pChipImageInfo->fAecTailLength = FALSE; + f_pChipImageInfo->fToneRemoval = FALSE; + + f_pChipImageInfo->fDefaultErl = FALSE; + f_pChipImageInfo->fNonLinearityBehaviorA = FALSE; + f_pChipImageInfo->fNonLinearityBehaviorB = FALSE; + f_pChipImageInfo->fPerChannelTailDisplacement = FALSE; + f_pChipImageInfo->fPerChannelTailLength = FALSE; + f_pChipImageInfo->fListenerEnhancement = FALSE; + f_pChipImageInfo->fRoutNoiseReduction = FALSE; + f_pChipImageInfo->fRoutNoiseReductionLevel = FALSE; + f_pChipImageInfo->fAnrSnrEnhancement = FALSE; + f_pChipImageInfo->fAnrVoiceNoiseSegregation = FALSE; + f_pChipImageInfo->fToneDisablerVqeActivationDelay = FALSE; + f_pChipImageInfo->fMusicProtection = FALSE; + f_pChipImageInfo->fDoubleTalkBehavior = FALSE; + f_pChipImageInfo->fIdleCodeDetection = TRUE; + f_pChipImageInfo->fSinLevel = TRUE; + + for ( i = 0; i < cOCT6100_MAX_TONE_EVENT; i++ ) + { + Oct6100UserMemSet( f_pChipImageInfo->aToneInfo[ i ].aszToneName, 0x00, cOCT6100_TLV_MAX_TONE_NAME_SIZE ); + f_pChipImageInfo->aToneInfo[ i ].ulDetectionPort = cOCT6100_INVALID_PORT; + f_pChipImageInfo->aToneInfo[ i ].ulToneID = cOCT6100_INVALID_VALUE; + } + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ChipGetImageInfo +UINT32 Oct6100ChipGetImageInfo( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CHIP_IMAGE_INFO f_pChipImageInfo ) +{ + tPOCT6100_API_IMAGE_INFO pImageInfo; + UINT32 i; + + /* Get local pointer(s). */ + pImageInfo = &f_pApiInstance->pSharedInfo->ImageInfo; + + Oct6100UserMemCopy( f_pChipImageInfo->szVersionNumber, pImageInfo->szVersionNumber, cOCT6100_VERSION_NUMBER_MAX_SIZE ); + + /* Copy the customer info. */ + f_pChipImageInfo->ulBuildId = pImageInfo->ulBuildId; + + /* Copy the features list. */ + f_pChipImageInfo->fBufferPlayout = pImageInfo->fBufferPlayout; + f_pChipImageInfo->fAdaptiveNoiseReduction = pImageInfo->fAdaptiveNoiseReduction; + f_pChipImageInfo->fSoutNoiseBleaching = pImageInfo->fSoutNoiseBleaching; + f_pChipImageInfo->fSilenceSuppression = pImageInfo->fSilenceSuppression; + + f_pChipImageInfo->fAdpcm = pImageInfo->fAdpcm; + f_pChipImageInfo->fConferencing = pImageInfo->fConferencing; + f_pChipImageInfo->fDominantSpeaker = pImageInfo->fDominantSpeakerEnabled; + f_pChipImageInfo->fConferencingNoiseReduction = pImageInfo->fConferencingNoiseReduction; + f_pChipImageInfo->fAcousticEcho = pImageInfo->fAcousticEcho; + f_pChipImageInfo->fAecTailLength = pImageInfo->fAecTailLength; + f_pChipImageInfo->fDefaultErl = pImageInfo->fDefaultErl; + f_pChipImageInfo->fToneRemoval = pImageInfo->fToneRemoval; + + f_pChipImageInfo->fNonLinearityBehaviorA = pImageInfo->fNonLinearityBehaviorA; + f_pChipImageInfo->fNonLinearityBehaviorB = pImageInfo->fNonLinearityBehaviorB; + f_pChipImageInfo->fPerChannelTailDisplacement = pImageInfo->fPerChannelTailDisplacement; + f_pChipImageInfo->fListenerEnhancement = pImageInfo->fListenerEnhancement; + f_pChipImageInfo->fRoutNoiseReduction = pImageInfo->fRoutNoiseReduction; + f_pChipImageInfo->fRoutNoiseReductionLevel = pImageInfo->fRoutNoiseReductionLevel; + f_pChipImageInfo->fAnrSnrEnhancement = pImageInfo->fAnrSnrEnhancement; + f_pChipImageInfo->fAnrVoiceNoiseSegregation = pImageInfo->fAnrVoiceNoiseSegregation; + f_pChipImageInfo->fMusicProtection = pImageInfo->fMusicProtection; + f_pChipImageInfo->fIdleCodeDetection = pImageInfo->fIdleCodeDetection; + f_pChipImageInfo->fSinLevel = pImageInfo->fSinLevel; + f_pChipImageInfo->fDoubleTalkBehavior = pImageInfo->fDoubleTalkBehavior; + f_pChipImageInfo->fHighLevelCompensation = pImageInfo->fRinHighLevelCompensation; + + if ( ( pImageInfo->fRinAutoLevelControl == TRUE ) && ( pImageInfo->fSoutAutoLevelControl == TRUE ) ) + f_pChipImageInfo->fAutoLevelControl = TRUE; + else + f_pChipImageInfo->fAutoLevelControl = FALSE; + + f_pChipImageInfo->ulMaxChannels = pImageInfo->usMaxNumberOfChannels; + f_pChipImageInfo->ulNumTonesAvailable = pImageInfo->byNumToneDetectors; + f_pChipImageInfo->ulToneProfileNumber = pImageInfo->ulToneProfileNumber; + f_pChipImageInfo->ulMaxTailDisplacement = pImageInfo->usMaxTailDisplacement; + f_pChipImageInfo->ulMaxTailLength = pImageInfo->usMaxTailLength; + f_pChipImageInfo->fPerChannelTailLength = pImageInfo->fPerChannelTailLength; + f_pChipImageInfo->ulDebugEventSize = f_pApiInstance->pSharedInfo->DebugInfo.ulDebugEventSize; + f_pChipImageInfo->fToneDisablerVqeActivationDelay = pImageInfo->fToneDisablerVqeActivationDelay; + f_pChipImageInfo->ulMaxPlayoutEvents = pImageInfo->byMaxNumberPlayoutEvents - 1; /* 127 or 31 */ + f_pChipImageInfo->ulImageType = pImageInfo->byImageType; + + for ( i = 0; i < cOCT6100_MAX_TONE_EVENT; i++ ) + { + Oct6100UserMemCopy( f_pChipImageInfo->aToneInfo[ i ].aszToneName, pImageInfo->aToneInfo[ i ].aszToneName, cOCT6100_TLV_MAX_TONE_NAME_SIZE ); + f_pChipImageInfo->aToneInfo[ i ].ulDetectionPort = pImageInfo->aToneInfo[ i ].ulDetectionPort; + f_pChipImageInfo->aToneInfo[ i ].ulToneID = pImageInfo->aToneInfo[ i ].ulToneID; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiChipStatsSwInit + +Description: Initializes portions of API instance associated to chip stats. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiChipStatsSwInit +UINT32 Oct6100ApiChipStatsSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + + /* Get local pointer to shared portion of API instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Initialize chip stats. */ + pSharedInfo->ErrorStats.fFatalChipError = FALSE; + + pSharedInfo->ErrorStats.ulH100ClkABadCnt = 0; + pSharedInfo->ErrorStats.ulH100ClkBBadCnt = 0; + pSharedInfo->ErrorStats.ulH100FrameABadCnt = 0; + pSharedInfo->ErrorStats.ulH100OutOfSyncCnt = 0; + + pSharedInfo->ErrorStats.ulInternalReadTimeoutCnt = 0; + pSharedInfo->ErrorStats.ulSdramRefreshTooLateCnt = 0; + pSharedInfo->ErrorStats.ulPllJitterErrorCnt = 0; + pSharedInfo->ErrorStats.ulOverflowToneEventsCnt = 0; + + + + pSharedInfo->ErrorStats.ulToneDetectorErrorCnt = 0; + + /* Init the chip stats. */ + pSharedInfo->ChipStats.usNumberChannels = 0; + pSharedInfo->ChipStats.usNumberBiDirChannels = 0; + pSharedInfo->ChipStats.usNumberTsiCncts = 0; + pSharedInfo->ChipStats.usNumberConfBridges = 0; + pSharedInfo->ChipStats.usNumberPlayoutBuffers = 0; + pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts = 0; + pSharedInfo->ChipStats.ulPlayoutMemUsed = 0; + pSharedInfo->ChipStats.usNumEcChanUsingMixer = 0; + + pSharedInfo->ChipStats.usNumberPhasingTssts = 0; + pSharedInfo->ChipStats.usNumberAdpcmChans = 0; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChipGetStatsSer + +Description: Serialized function retreiving the chip statistics. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChipStats Pointer to master mode configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChipGetStatsSer +UINT32 Oct6100ChipGetStatsSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT tPOCT6100_CHIP_STATS f_pChipStats ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + f_pChipStats->ulNumberChannels = pSharedInfo->ChipStats.usNumberChannels; + f_pChipStats->ulNumberTsiCncts = pSharedInfo->ChipStats.usNumberTsiCncts; + f_pChipStats->ulNumberConfBridges = pSharedInfo->ChipStats.usNumberConfBridges; + f_pChipStats->ulNumberPlayoutBuffers = pSharedInfo->ChipStats.usNumberPlayoutBuffers; + f_pChipStats->ulPlayoutFreeMemSize = ( f_pApiInstance->pSharedInfo->MiscVars.ulTotalMemSize - ( f_pApiInstance->pSharedInfo->MemoryMap.ulFreeMemBaseAddress - cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) ) - ( pSharedInfo->ChipStats.ulPlayoutMemUsed ); + + f_pChipStats->ulNumberPhasingTssts = pSharedInfo->ChipStats.usNumberPhasingTssts; + f_pChipStats->ulNumberAdpcmChannels = pSharedInfo->ChipStats.usNumberAdpcmChans; + + /* Check the input parameters. */ + if ( f_pChipStats->fResetChipStats != TRUE && + f_pChipStats->fResetChipStats != FALSE ) + return cOCT6100_ERR_CHIP_STATS_RESET; + + if ( f_pChipStats->fResetChipStats == TRUE ) + { + pSharedInfo->ErrorStats.ulH100OutOfSyncCnt = 0; + pSharedInfo->ErrorStats.ulH100ClkABadCnt = 0; + pSharedInfo->ErrorStats.ulH100FrameABadCnt = 0; + pSharedInfo->ErrorStats.ulH100ClkBBadCnt = 0; + + pSharedInfo->ErrorStats.ulInternalReadTimeoutCnt = 0; + pSharedInfo->ErrorStats.ulPllJitterErrorCnt = 0; + pSharedInfo->ErrorStats.ulSdramRefreshTooLateCnt = 0; + + pSharedInfo->ErrorStats.ulOverflowToneEventsCnt = 0; + pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt = 0; + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt = 0; + + + } + + f_pChipStats->ulH100OutOfSynchCount = pSharedInfo->ErrorStats.ulH100OutOfSyncCnt; + f_pChipStats->ulH100ClockABadCount = pSharedInfo->ErrorStats.ulH100ClkABadCnt; + f_pChipStats->ulH100FrameABadCount = pSharedInfo->ErrorStats.ulH100FrameABadCnt; + f_pChipStats->ulH100ClockBBadCount = pSharedInfo->ErrorStats.ulH100ClkBBadCnt; + + f_pChipStats->ulInternalReadTimeoutCount = pSharedInfo->ErrorStats.ulInternalReadTimeoutCnt; + f_pChipStats->ulPllJitterErrorCount = pSharedInfo->ErrorStats.ulPllJitterErrorCnt; + f_pChipStats->ulSdramRefreshTooLateCount = pSharedInfo->ErrorStats.ulSdramRefreshTooLateCnt; + + f_pChipStats->ulOverflowToneEventsCount = pSharedInfo->ErrorStats.ulOverflowToneEventsCnt; + f_pChipStats->ulSoftOverflowToneEventsCount = pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt; + f_pChipStats->ulSoftOverflowBufferPlayoutEventsCount = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt; + + + + return cOCT6100_ERR_OK; +} +#endif + diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_conf_bridge.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_conf_bridge.c new file mode 100644 index 0000000..1b279d6 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_conf_bridge.c @@ -0,0 +1,7664 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_conf_bridge.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains all functions related to a conference bridge. Procedures + needed to open/close a bridge, add/remove a participant to a conference + bridge, mute/unmute a participant, etc.. are all present in this source + file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 146 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_mixer_inst.h" +#include "oct6100api/oct6100_conf_bridge_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_mixer_pub.h" +#include "oct6100api/oct6100_conf_bridge_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_tsst_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_mixer_priv.h" +#include "oct6100_conf_bridge_priv.h" + + +/**************************** PUBLIC FUNCTIONS *****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeOpen + +Description: This function opens a conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeOpen Pointer to conference bridge open structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeOpenDef +UINT32 Oct6100ConfBridgeOpenDef( + tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ) +{ + f_pConfBridgeOpen->pulConfBridgeHndl = NULL; + f_pConfBridgeOpen->fFlexibleConferencing = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeOpen +UINT32 Oct6100ConfBridgeOpen( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeOpenSer( f_pApiInstance, f_pConfBridgeOpen ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeClose + +Description: This function closes a conference bridge. A conference + bridge can only be closed if no participants are present on + the bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeClose Pointer to conference bridge close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeCloseDef +UINT32 Oct6100ConfBridgeCloseDef( + tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose ) +{ + f_pConfBridgeClose->ulConfBridgeHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeClose +UINT32 Oct6100ConfBridgeClose( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeCloseSer( f_pApiInstance, f_pConfBridgeClose ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeChanAdd + +Description: This function adds an echo channel (participant) to a + conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeAdd Pointer to conference bridge channel addition structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeChanAddDef +UINT32 Oct6100ConfBridgeChanAddDef( + tPOCT6100_CONF_BRIDGE_CHAN_ADD f_pConfBridgeAdd ) +{ + f_pConfBridgeAdd->ulConfBridgeHndl = cOCT6100_INVALID_HANDLE; + f_pConfBridgeAdd->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pConfBridgeAdd->ulInputPort = cOCT6100_CHANNEL_PORT_SOUT; + f_pConfBridgeAdd->ulListenerMaskIndex = cOCT6100_INVALID_VALUE; + f_pConfBridgeAdd->ulListenerMask = 0; + f_pConfBridgeAdd->fMute = FALSE; + f_pConfBridgeAdd->ulTappedChannelHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeChanAdd +UINT32 Oct6100ConfBridgeChanAdd( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_CHAN_ADD f_pConfBridgeAdd ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeChanAddSer( f_pApiInstance, f_pConfBridgeAdd ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeChanRemove + +Description: This function removes an echo channel (participant) from a + conference bridge. All participants can be removed from + the bridge if a special flag (fRemoveAll) is set to TRUE. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeRemove Pointer to conference bridge channel removal structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeChanRemoveDef +UINT32 Oct6100ConfBridgeChanRemoveDef( + tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove ) +{ + f_pConfBridgeRemove->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pConfBridgeRemove->ulConfBridgeHndl = cOCT6100_INVALID_HANDLE; + f_pConfBridgeRemove->fRemoveAll = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeChanRemove +UINT32 Oct6100ConfBridgeChanRemove( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeChanRemoveSer( f_pApiInstance, f_pConfBridgeRemove ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeChanMute + +Description: This function mutes a participant present on a conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeMute Pointer to conference bridge channel mute structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeChanMuteDef +UINT32 Oct6100ConfBridgeChanMuteDef( + tPOCT6100_CONF_BRIDGE_CHAN_MUTE f_pConfBridgeMute ) +{ + f_pConfBridgeMute->ulChannelHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeChanMute +UINT32 Oct6100ConfBridgeChanMute( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_CHAN_MUTE f_pConfBridgeMute ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeChanMuteSer( f_pApiInstance, f_pConfBridgeMute ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeChanUnMute + +Description: This function unmutes a channel on a bridge. The other member + of the conference will start to hear this participant again. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeUnMute Pointer to conference bridge channel unmute structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeChanUnMuteDef +UINT32 Oct6100ConfBridgeChanUnMuteDef( + tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE f_pConfBridgeUnMute ) +{ + f_pConfBridgeUnMute->ulChannelHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ConfBridgeChanUnMute +UINT32 Oct6100ConfBridgeChanUnMute( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE f_pConfBridgeUnMute ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeChanUnMuteSer( f_pApiInstance, f_pConfBridgeUnMute ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeDominantSpeakerSet + +Description: This function sets a participant present on a conference + bridge as the dominant speaker. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to + keep the present state of the chip and all its + resources. + +f_pConfBridgeDominant Pointer to conference bridge dominant speaker + structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeDominantSpeakerSetDef +UINT32 Oct6100ConfBridgeDominantSpeakerSetDef( + tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET f_pConfBridgeDominantSpeaker ) +{ + f_pConfBridgeDominantSpeaker->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pConfBridgeDominantSpeaker->ulConfBridgeHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeDominantSpeakerSet +UINT32 Oct6100ConfBridgeDominantSpeakerSet( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET f_pConfBridgeDominantSpeaker ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeDominantSpeakerSetSer( f_pApiInstance, f_pConfBridgeDominantSpeaker ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeMaskChange + +Description: This function changes the mask of a flexible bridge participant. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to + keep the present state of the chip and all its + resources. + +f_pConfBridgeMaskChange Pointer to conference bridge change of mask + structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeMaskChangeDef +UINT32 Oct6100ConfBridgeMaskChangeDef( + tPOCT6100_CONF_BRIDGE_MASK_CHANGE f_pConfBridgeMaskChange ) +{ + f_pConfBridgeMaskChange->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pConfBridgeMaskChange->ulNewListenerMask = 0x0; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeMaskChange +UINT32 Oct6100ConfBridgeMaskChange( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_MASK_CHANGE f_pConfBridgeMaskChange ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeMaskChangeSer( f_pApiInstance, f_pConfBridgeMaskChange ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeGetStats + +Description: This function returns the stats for a conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeStats Pointer to conference bridge channel stats structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeGetStatsDef +UINT32 Oct6100ConfBridgeGetStatsDef( + tPOCT6100_CONF_BRIDGE_STATS f_pConfBridgeStats ) +{ + f_pConfBridgeStats->ulConfBridgeHndl = cOCT6100_INVALID_HANDLE; + f_pConfBridgeStats->ulNumChannels = cOCT6100_INVALID_STAT; + f_pConfBridgeStats->ulNumTappedChannels = cOCT6100_INVALID_STAT; + f_pConfBridgeStats->fFlexibleConferencing = cOCT6100_INVALID_STAT; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeGetStats +UINT32 Oct6100ConfBridgeGetStats( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_STATS f_pConfBridgeStats ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeGetStatsSer( f_pApiInstance, f_pConfBridgeStats ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + +/**************************** PRIVATE FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetConfBridgeSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of conference bridges. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pOpenChip Pointer to chip configuration struct. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetConfBridgeSwSizes +UINT32 Oct6100ApiGetConfBridgeSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + + /* Calculate memory needed for conference bridge list. */ + if ( f_pOpenChip->ulMaxConfBridges == 0 && f_pOpenChip->fEnableChannelRecording == TRUE ) + f_pOpenChip->ulMaxConfBridges = 1; + f_pInstSizes->ulConfBridgeList = f_pOpenChip->ulMaxConfBridges * sizeof( tOCT6100_API_CONF_BRIDGE ); + + /* Calculate memory needed for conference bridge allocation software. */ + if ( f_pOpenChip->ulMaxConfBridges > 0 ) + { + /* Get size of bridge allocation memory */ + ulResult = OctapiLlmAllocGetSize( f_pOpenChip->ulMaxConfBridges, &f_pInstSizes->ulConfBridgeAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1C; + + /* Check if the user wants to build flexible conference bridges. */ + if ( f_pOpenChip->ulMaxFlexibleConfParticipants > 0 ) + { + /* Allocate the lowest quantity according to what the user requested. */ + if ( f_pOpenChip->ulMaxFlexibleConfParticipants < ( f_pOpenChip->ulMaxConfBridges * cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE ) ) + f_pInstSizes->ulFlexConfParticipantsList = f_pOpenChip->ulMaxFlexibleConfParticipants * sizeof( tOCT6100_API_FLEX_CONF_PARTICIPANT ); + else + { + f_pOpenChip->ulMaxFlexibleConfParticipants = f_pOpenChip->ulMaxConfBridges * cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; + f_pInstSizes->ulFlexConfParticipantsList = f_pOpenChip->ulMaxConfBridges * cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE * sizeof( tOCT6100_API_FLEX_CONF_PARTICIPANT ); + } + + /* Get size of flexible conferencing participants allocation memory */ + ulResult = OctapiLlmAllocGetSize( f_pOpenChip->ulMaxFlexibleConfParticipants, &f_pInstSizes->ulFlexConfParticipantsAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1C; + } + else + { + f_pInstSizes->ulFlexConfParticipantsList = 0; + f_pInstSizes->ulFlexConfParticipantsAlloc = 0; + } + } + else + { + f_pInstSizes->ulMixerEventList = 0; + f_pInstSizes->ulMixerEventAlloc = 0; + f_pInstSizes->ulConfBridgeAlloc = 0; + + /* Make sure flexible conferencing is not used. */ + f_pInstSizes->ulFlexConfParticipantsList = 0; + f_pInstSizes->ulFlexConfParticipantsAlloc = 0; + } + + /* Calculate memory needed for list and allocation software serialization. */ + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulConfBridgeList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulConfBridgeAlloc, ulTempVar ) + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulFlexConfParticipantsList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulFlexConfParticipantsAlloc, ulTempVar ) + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiConfBridgeSwInit + +Description: Initializes all elements of the instance structure associated + to conference bridges. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiConfBridgeSwInit +UINT32 Oct6100ApiConfBridgeSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CONF_BRIDGE pConfBridgeList; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pFlexConfParticipantList; + PVOID pFlexConfPartipantsAlloc; + UINT32 ulMaxFlexConfParicipants; + PVOID pConfBridgeAlloc; + UINT32 ulMaxConfBridges; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get the maximum number of conference bridges. */ + ulMaxConfBridges = pSharedInfo->ChipConfig.usMaxConfBridges; + + /*===================================================================*/ + /* Set all entries in the conference bridge list to unused. */ + + mOCT6100_GET_CONF_BRIDGE_LIST_PNT( pSharedInfo, pConfBridgeList ); + + /* Initialize the conference bridge allocation software to "all free". */ + if ( ulMaxConfBridges > 0 ) + { + /* Clear the bridge memory */ + Oct6100UserMemSet( pConfBridgeList, 0x00, ulMaxConfBridges * sizeof( tOCT6100_API_CONF_BRIDGE )); + + mOCT6100_GET_CONF_BRIDGE_ALLOC_PNT( pSharedInfo, pConfBridgeAlloc ) + + ulResult = OctapiLlmAllocInit( &pConfBridgeAlloc, ulMaxConfBridges ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1E; + } + /*===================================================================*/ + + + /*===================================================================*/ + /* Set all entries in the flexible conferencing participant list to unused. */ + + /* Get the maximum number of flexible conferencing participants. */ + ulMaxFlexConfParicipants = pSharedInfo->ChipConfig.usMaxFlexibleConfParticipants; + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_LIST_PNT( pSharedInfo, pFlexConfParticipantList ); + + /* Initialize the flexible conferencing allocation software. */ + if ( ulMaxFlexConfParicipants > 0 ) + { + UINT32 i, ulEventIndex; + + /* Clear the participants memory */ + Oct6100UserMemSet( pFlexConfParticipantList, 0x00, ulMaxFlexConfParicipants * sizeof( tOCT6100_API_FLEX_CONF_PARTICIPANT )); + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ALLOC_PNT( pSharedInfo, pFlexConfPartipantsAlloc ) + + ulResult = OctapiLlmAllocInit( &pFlexConfPartipantsAlloc, ulMaxFlexConfParicipants ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1E; + + /* Initialize the conferencing indexes. */ + for ( i = 0; i < ulMaxFlexConfParicipants; i ++ ) + { + for ( ulEventIndex = 0; ulEventIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulEventIndex ++ ) + pFlexConfParticipantList[ i ].ausLoadOrAccumulateEventIndex[ ulEventIndex ] = cOCT6100_INVALID_INDEX; + } + } + + /*===================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeOpenSer + +Description: Open a conference bridge. Note that no chip resources are + allocated until a channel is added to the bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeOpen Pointer to conference bridge configuration structure. + The handle identifying the conference bridge in all + future function calls is returned in this structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeOpenSer +UINT32 Oct6100ConfBridgeOpenSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ) +{ + UINT16 usBridgeIndex; + UINT32 ulResult; + + /* Check the user's configuration of the conference bridge for errors. */ + ulResult = Oct6100ApiCheckBridgeParams( f_pApiInstance, f_pConfBridgeOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the conference bridge. */ + ulResult = Oct6100ApiReserveBridgeResources( f_pApiInstance, &usBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the new conference bridge's entry in the conference bridge list. */ + ulResult = Oct6100ApiUpdateBridgeEntry( f_pApiInstance, f_pConfBridgeOpen, usBridgeIndex); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckBridgeParams + +Description: Checks the user's conference bridge open configuration for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeOpen Pointer to conference bridge configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckBridgeParams +UINT32 Oct6100ApiCheckBridgeParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ) +{ + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges == 0 ) + return cOCT6100_ERR_CONF_BRIDGE_DISABLED; + + if ( f_pConfBridgeOpen->pulConfBridgeHndl == NULL ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fConferencing == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CONF_BRIDGE; + + if ( f_pConfBridgeOpen->fFlexibleConferencing != FALSE + && f_pConfBridgeOpen->fFlexibleConferencing != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveBridgeResources + +Description: Reserves all resources needed for the new conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pusBridgeIndex Allocated entry in the API conference bridge list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveBridgeResources +UINT32 Oct6100ApiReserveBridgeResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusBridgeIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Reserve an entry in the conference bridge list. */ + ulResult = Oct6100ApiReserveBridgeEntry( f_pApiInstance, f_pusBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateBridgeEntry + +Description: Updates the new conference bridge's entry in the conference + bridge list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pConfBridgeOpen Pointer to conference bridge configuration structure. +f_usBridgeIndex Allocated entry in API conference bridge list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateBridgeEntry +UINT32 Oct6100ApiUpdateBridgeEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen, + IN UINT16 f_usBridgeIndex ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + tPOCT6100_API_CONF_BRIDGE pTempBridgeEntry; + + /*================================================================================*/ + /* Obtain a pointer to the new conference bridge's list entry. */ + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, f_usBridgeIndex ) + + /* No clients are currently connected to the bridge. */ + pBridgeEntry->usNumClients = 0; + /* Nobody is tapped for now. */ + pBridgeEntry->usNumTappedClients = 0; + pBridgeEntry->usFirstLoadEventPtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usFirstSubStoreEventPtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usLastSubStoreEventPtr = cOCT6100_INVALID_INDEX; + + pBridgeEntry->usSilenceLoadEventPtr = cOCT6100_INVALID_INDEX; + + pBridgeEntry->usLoadIndex = cOCT6100_INVALID_INDEX; + + /* Now update the bridge pointer. */ + if ( f_pApiInstance->pSharedInfo->MiscVars.usNumBridgesOpened == 0 ) + { + pBridgeEntry->usNextBridgePtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usPrevBridgePtr = cOCT6100_INVALID_INDEX; + + /* Set the global first bridge to this bridge. */ + f_pApiInstance->pSharedInfo->MiscVars.usFirstBridge = f_usBridgeIndex; + } + else /* Insert this bridge at the head of the bridge list.*/ + { + if ( f_pApiInstance->pSharedInfo->MiscVars.usFirstBridge == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_FATAL_22; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTempBridgeEntry, f_pApiInstance->pSharedInfo->MiscVars.usFirstBridge ) + + if ( pTempBridgeEntry->fReserved != TRUE ) + return cOCT6100_ERR_FATAL_23; + + /* Modify the old first entry. */ + pTempBridgeEntry->usPrevBridgePtr = f_usBridgeIndex; + + /* Modify current pointer. */ + pBridgeEntry->usPrevBridgePtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usNextBridgePtr = f_pApiInstance->pSharedInfo->MiscVars.usFirstBridge; + + /* Set the new first bridge of the list. */ + f_pApiInstance->pSharedInfo->MiscVars.usFirstBridge = f_usBridgeIndex; + } + + /* Form handle returned to user. */ + *f_pConfBridgeOpen->pulConfBridgeHndl = cOCT6100_HNDL_TAG_CONF_BRIDGE | (pBridgeEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_usBridgeIndex; + + /* Remember whether or not we are a flexible conference bridge. */ + pBridgeEntry->fFlexibleConferencing = (UINT8)( f_pConfBridgeOpen->fFlexibleConferencing & 0xFF ); + + /* Finally, mark the conference bridge as opened. */ + pBridgeEntry->fReserved = TRUE; + + /* Increment the number of conference bridge opened. */ + f_pApiInstance->pSharedInfo->ChipStats.usNumberConfBridges++; + f_pApiInstance->pSharedInfo->MiscVars.usNumBridgesOpened++; + + /*================================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeCloseSer + +Description: Closes a conference bridge. Note that no client must be present + on the bridge for the bridge to be closed. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeClose Pointer to conference bridge close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeCloseSer +UINT32 Oct6100ConfBridgeCloseSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose ) +{ + UINT16 usBridgeIndex; + UINT32 ulResult; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertBridgeParams( f_pApiInstance, f_pConfBridgeClose, &usBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the conference bridge. */ + ulResult = Oct6100ApiReleaseBridgeResources( f_pApiInstance, usBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Invalidate the handle. */ + f_pConfBridgeClose->ulConfBridgeHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertBridgeParams + +Description: Checks the user's conference bridge close configuration for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeClose Pointer to conference bridge close structure. +f_pusBridgeIndex Pointer to API instance conference bridge index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertBridgeParams +UINT32 Oct6100ApiAssertBridgeParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose, + OUT PUINT16 f_pusBridgeIndex ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + UINT32 ulEntryOpenCnt; + + /* Check the provided handle. */ + if ( (f_pConfBridgeClose->ulConfBridgeHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CONF_BRIDGE ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + *f_pusBridgeIndex = (UINT16)( f_pConfBridgeClose->ulConfBridgeHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusBridgeIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, *f_pusBridgeIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeClose->ulConfBridgeHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pBridgeEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( pBridgeEntry->usNumClients != 0 ) + return cOCT6100_ERR_CONF_BRIDGE_ACTIVE_DEPENDENCIES; + if ( ulEntryOpenCnt != pBridgeEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseBridgeResources + +Description: Release all resources reserved for the conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usBridgeIndex Allocated external memory block for the conference bridge. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseBridgeResources +UINT32 Oct6100ApiReleaseBridgeResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBridgeIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + tPOCT6100_API_CONF_BRIDGE pTempBridgeEntry; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Release the entry from the conference bridge list. */ + ulResult = Oct6100ApiReleaseBridgeEntry( f_pApiInstance, f_usBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_24; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, f_usBridgeIndex ); + + /* Remove the bridge entry from the bridge list. */ + if ( pSharedInfo->MiscVars.usNumBridgesOpened == 1 ) + { + /* This bridge was the only one opened. */ + pSharedInfo->MiscVars.usFirstBridge = cOCT6100_INVALID_INDEX; + } + else if ( pSharedInfo->MiscVars.usNumBridgesOpened > 1 ) + { + /* There are more then one bridge open, must update the list. */ + if ( pBridgeEntry->usPrevBridgePtr != cOCT6100_INVALID_INDEX ) + { + /* There is a valid entry before this bridge, let's update this entry. */ + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTempBridgeEntry, pBridgeEntry->usPrevBridgePtr ); + + pTempBridgeEntry->usNextBridgePtr = pBridgeEntry->usNextBridgePtr; + } + + if ( pBridgeEntry->usNextBridgePtr != cOCT6100_INVALID_INDEX ) + { + /* There is a valid entry after this bridge, let's update this entry. */ + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTempBridgeEntry, pBridgeEntry->usNextBridgePtr ); + + pTempBridgeEntry->usPrevBridgePtr = pBridgeEntry->usPrevBridgePtr; + } + + if ( pSharedInfo->MiscVars.usFirstBridge == f_usBridgeIndex ) + { + /* This entry was the first of the list, make the next one be the first now. */ + pSharedInfo->MiscVars.usFirstBridge = pBridgeEntry->usNextBridgePtr; + } + } + else + { + /* Variable has become out of sync. */ + return cOCT6100_ERR_FATAL_25; + } + + /*=============================================================*/ + /* Update the conference bridge's list entry. */ + + /* Mark the bridge as closed. */ + pBridgeEntry->fFlexibleConferencing = FALSE; + pBridgeEntry->fReserved = FALSE; + pBridgeEntry->byEntryOpenCnt++; + + /* Decrement the number of conference bridges opened. */ + pSharedInfo->MiscVars.usNumBridgesOpened--; + pSharedInfo->ChipStats.usNumberConfBridges--; + + /*=============================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeChanAddSer + +Description: Adds an echo channel (participant) to a conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeAdd Pointer to conference bridge channel add structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeChanAddSer +UINT32 Oct6100ConfBridgeChanAddSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CHAN_ADD f_pConfBridgeAdd ) +{ + UINT16 usBridgeIndex; + UINT16 usChanIndex; + UINT16 usLoadEventIndex; + UINT16 usSubStoreEventIndex; + UINT16 usCopyEventIndex; + UINT32 ulInputPort; + UINT8 fFlexibleConfBridge; + UINT32 ulListenerMaskIndex; + UINT32 ulListenerMask; + UINT16 usTapChanIndex; + UINT16 usTapBridgeIndex; + UINT8 fMute; + UINT8 fTap; + UINT32 ulResult; + + /* Check the validity of the channel and conference bridge given. */ + ulResult = Oct6100ApiCheckBridgeAddParams( + f_pApiInstance, + f_pConfBridgeAdd, + &usBridgeIndex, + &usChanIndex, + &fMute, + &ulInputPort, + &fFlexibleConfBridge, + &ulListenerMaskIndex, + &ulListenerMask, + &fTap, + &usTapChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the conference bridge. */ + ulResult = Oct6100ApiReserveBridgeAddResources( + f_pApiInstance, + usBridgeIndex, + usChanIndex, + ulInputPort, + fFlexibleConfBridge, + ulListenerMaskIndex, + ulListenerMask, + fTap, + &usLoadEventIndex, + &usSubStoreEventIndex, + &usCopyEventIndex, + &usTapBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the conference bridge. */ + ulResult = Oct6100ApiBridgeEventAdd( + f_pApiInstance, + usBridgeIndex, + usChanIndex, + fFlexibleConfBridge, + usLoadEventIndex, + usSubStoreEventIndex, + usCopyEventIndex, + ulInputPort, + fMute, + ulListenerMaskIndex, + ulListenerMask, + fTap, + usTapBridgeIndex, + usTapChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckBridgeAddParams + +Description: Check the validity of the channel and conference bridge given. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_pConfBridgeAdd Pointer to conference bridge channenl add structure. +f_pusBridgeIndex Extracted bridge index where this channel should be + added. +f_pusChannelIndex Extracted channel index related to the channel handle + to be added to the bridge. +f_pfMute Whether to mute this channel in the bridge or not. +f_pulInputPort Input port where the channel signal should be + copied from. +f_pfFlexibleConfBridge If this is a flexible conference bridge. +f_pulListenerMaskIndex Index of the listener in this flexible conference bridge. +f_pulListenerMask Mask of listeners in this flexible conference bridge. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckBridgeAddParams +UINT32 Oct6100ApiCheckBridgeAddParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CHAN_ADD f_pConfBridgeAdd, + OUT PUINT16 f_pusBridgeIndex, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT8 f_pfMute, + OUT PUINT32 f_pulInputPort, + OUT PUINT8 f_pfFlexibleConfBridge, + OUT PUINT32 f_pulListenerMaskIndex, + OUT PUINT32 f_pulListenerMask, + OUT PUINT8 f_pfTap, + OUT PUINT16 f_pusTapChannelIndex ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + tPOCT6100_API_CHANNEL pEchoChanEntry; + UINT32 ulEntryOpenCnt; + UINT8 byTapChannelLaw; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges == 0 ) + return cOCT6100_ERR_CONF_BRIDGE_DISABLED; + + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges == 1 && + f_pApiInstance->pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_DISABLED; + + if ( f_pConfBridgeAdd->ulConfBridgeHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + if ( f_pConfBridgeAdd->ulChannelHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_HANDLE; + + if( f_pConfBridgeAdd->ulInputPort != cOCT6100_CHANNEL_PORT_SOUT + && f_pConfBridgeAdd->ulInputPort != cOCT6100_CHANNEL_PORT_RIN ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_INPUT_PORT; + + if ( f_pConfBridgeAdd->fMute != TRUE && f_pConfBridgeAdd->fMute != FALSE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_MUTE; + + /*=====================================================================*/ + /* Check the conference bridge handle. */ + + if ( (f_pConfBridgeAdd->ulConfBridgeHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CONF_BRIDGE ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + *f_pusBridgeIndex = (UINT16)( f_pConfBridgeAdd->ulConfBridgeHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusBridgeIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, *f_pusBridgeIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeAdd->ulConfBridgeHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pBridgeEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( ulEntryOpenCnt != pBridgeEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + /* When we a flexible conference bridge, more things need to be checked. */ + if ( pBridgeEntry->fFlexibleConferencing == TRUE ) + { + /* Check if flexible conferencing has been activated. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxFlexibleConfParticipants == 0 ) + return cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_DISABLED; + + /* Check the number of clients on the bridge. */ + if ( pBridgeEntry->usNumClients >= cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE ) + return cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_PARTICIPANT_CNT; + + /* Check if the listener index in a flexible bridge is valid. */ + if ( f_pConfBridgeAdd->ulListenerMaskIndex == cOCT6100_INVALID_VALUE + || f_pConfBridgeAdd->ulListenerMaskIndex >= cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE ) + return cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_LISTENER_MASK_INDEX; + } + + if ( f_pConfBridgeAdd->ulTappedChannelHndl != cOCT6100_INVALID_HANDLE ) + { + if ( pBridgeEntry->fFlexibleConferencing == TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_TAP_NOT_SUPPORTED; + } + + /*=====================================================================*/ + + + /*=====================================================================*/ + /* Check the channel handle. */ + + if ( (f_pConfBridgeAdd->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_HANDLE; + + *f_pusChannelIndex = (UINT16)( f_pConfBridgeAdd->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_HANDLE; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChanEntry, *f_pusChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeAdd->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + if ( pEchoChanEntry->usBridgeIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ALREADY_ON_BRIDGE; + if ( pEchoChanEntry->fBiDirChannel == TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_BIDIR; + /* Law conversion is not allowed on a conference bridge. */ + if ( ( pEchoChanEntry->TdmConfig.usRinTimeslot != cOCT6100_UNASSIGNED ) + && ( pEchoChanEntry->TdmConfig.usRoutTimeslot != cOCT6100_UNASSIGNED ) ) + { + if ( pEchoChanEntry->TdmConfig.byRinPcmLaw != pEchoChanEntry->TdmConfig.byRoutPcmLaw ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_LAW_CONVERSION; + } + if ( ( pEchoChanEntry->TdmConfig.usSinTimeslot != cOCT6100_UNASSIGNED ) + && ( pEchoChanEntry->TdmConfig.usSoutTimeslot != cOCT6100_UNASSIGNED ) ) + { + if ( pEchoChanEntry->TdmConfig.bySinPcmLaw != pEchoChanEntry->TdmConfig.bySoutPcmLaw ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_LAW_CONVERSION; + } + if ( pEchoChanEntry->fRinRoutCodecActive == TRUE || pEchoChanEntry->fSinSoutCodecActive == TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_CODEC_ACTIVE; + if ( pEchoChanEntry->fEnableExtToneDetection == TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_EXT_TONE_ENABLED; + if ( pEchoChanEntry->usCopyEventCnt != 0x0 ) + return cOCT6100_ERR_CONF_BRIDGE_COPY_EVENTS; + + /* If the bridge is flexible, few more things need to be checked. */ + if ( pBridgeEntry->fFlexibleConferencing == TRUE ) + { + tPOCT6100_SHARED_INFO pSharedInfo; + UINT16 usChannelIndex; + UINT32 ulResult = cOCT6100_ERR_OK; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check if the listener index has been used by another channel in the specified bridge. */ + for ( usChannelIndex = 0; ( usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels ) && ( ulResult == cOCT6100_ERR_OK ) ; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, usChannelIndex ); + + /* Channel reserved? */ + if ( ( usChannelIndex != ( *f_pusChannelIndex ) ) && ( pEchoChanEntry->fReserved == TRUE ) ) + { + /* On current bridge? */ + if ( pEchoChanEntry->usBridgeIndex == ( *f_pusBridgeIndex ) ) + { + tPOCT6100_API_FLEX_CONF_PARTICIPANT pCurrentParticipant; + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pCurrentParticipant, pEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if this participant has the same listener index. */ + if ( f_pConfBridgeAdd->ulListenerMaskIndex == pCurrentParticipant->ulListenerMaskIndex ) + return cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_LISTENER_INDEX_USED; + } + } + } + } + + if ( f_pConfBridgeAdd->ulTappedChannelHndl != cOCT6100_INVALID_HANDLE ) + { + /* For internal logic, make sure the mute flag is set to false. */ + f_pConfBridgeAdd->fMute = FALSE; + + /* Force input port to Sout for logic below. */ + f_pConfBridgeAdd->ulInputPort = cOCT6100_CHANNEL_PORT_SOUT; + + /* Keep law to check for conversion. */ + /* Check if the same law. */ + byTapChannelLaw = pEchoChanEntry->TdmConfig.bySoutPcmLaw; + + /* Check the tap handle. */ + if ( (f_pConfBridgeAdd->ulTappedChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_TAP_HANDLE; + + *f_pusTapChannelIndex = (UINT16)( f_pConfBridgeAdd->ulTappedChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusTapChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_TAP_HANDLE; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChanEntry, *f_pusTapChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeAdd->ulTappedChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_TAP_HANDLE; + if ( pEchoChanEntry->usBridgeIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_NOT_ON_BRIDGE; + if ( pEchoChanEntry->usBridgeIndex != *f_pusBridgeIndex ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_NOT_ON_SAME_BRIDGE; + + /* We can only tap a channel added on the Sout port. */ + if ( pEchoChanEntry->usSinCopyEventIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_TAP_SOUT_ONLY; + + /* Check if already tapped. */ + if ( pEchoChanEntry->fBeingTapped == TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_ALREADY_TAPPED; + } + + /*=====================================================================*/ + + /* Return the tap flag. */ + if ( f_pConfBridgeAdd->ulTappedChannelHndl != cOCT6100_INVALID_HANDLE ) + { + *f_pfTap = TRUE; + } + else + { + *f_pfTap = FALSE; + } + + /* Return the mute config specified. */ + *f_pfMute = (UINT8)( f_pConfBridgeAdd->fMute & 0xFF ); + + /* Return the input port specified. */ + *f_pulInputPort = f_pConfBridgeAdd->ulInputPort; + + /* Return whether we are in the flexible conference bridge case. */ + *f_pfFlexibleConfBridge = pBridgeEntry->fFlexibleConferencing; + + /* Return the listener mask index as specified. */ + *f_pulListenerMaskIndex = f_pConfBridgeAdd->ulListenerMaskIndex; + + /* Return the listener mask as specified. */ + *f_pulListenerMask = f_pConfBridgeAdd->ulListenerMask; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveBridgeAddResources + +Description: Reserves all resources needed for the addition of a channel to + the conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_usBridgeIndex Bridge index of the bridge where this channel is added. +f_usChanIndex Channel index of the channel to be added to the bridge. +f_ulInputPort Input port where to copy samples from. +f_fFlexibleConfBridge If this is a flexible conference bridge. +f_ulListenerMaskIndex Index of the listener in this flexible conference bridge. +f_ulListenerMask Mask of listeners in this flexible conference bridge. +f_pusLoadEventIndex Load event index within the API's list of mixer event. +f_pusSubStoreEventIndex Sub-Store event index within the API's list of mixer event. +f_pusCopyEventIndex Copy event index within the API's list of mixer event. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveBridgeAddResources +UINT32 Oct6100ApiReserveBridgeAddResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChanIndex, + IN UINT32 f_ulInputPort, + IN UINT8 f_fFlexibleConfBridge, + IN UINT32 f_ulListenerMaskIndex, + IN UINT32 f_ulListenerMask, + IN UINT8 f_fTap, + OUT PUINT16 f_pusLoadEventIndex, + OUT PUINT16 f_pusSubStoreEventIndex, + OUT PUINT16 f_pusCopyEventIndex, + OUT PUINT16 f_pusTapBridgeIndex ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pTempEchoChanEntry; + UINT32 ulResult; + UINT32 ulTempVar; + UINT16 usChannelIndex; + BOOL fLoadEventReserved = FALSE; + BOOL fStoreEventReserved = FALSE; + BOOL fCopyEventReserved = FALSE; + BOOL fExtraSinTsiReserved = FALSE; + BOOL fExtraRinTsiReserved = FALSE; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ) + + /* Resources must be reserved according to the type of bridge we are adding to. */ + if ( f_fFlexibleConfBridge == TRUE ) + { + tPOCT6100_API_FLEX_CONF_PARTICIPANT pNewParticipant; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pCurrentParticipant; + + /*========================================================================*/ + /* If we are in the flexible conferencing case, things are a little */ + /* different. We create a mixer for every participant instead of the */ + /* usual same mixer for everyone. For example, if we have 3 participants */ + /* of type client - agent - coach, we build the mixers as follows: */ + /* */ + /* Client: - Load Agent */ + /* - Store */ + /* */ + /* Agent: - Load Client */ + /* - Accumulate Coach */ + /* - Store */ + /* */ + /* Coach: - Load Client */ + /* - Accumulate Agent */ + /* - Store */ + /* */ + /*========================================================================*/ + + /* First reserve a flexible conferencing participant entry. */ + ulResult = Oct6100ApiReserveFlexConfParticipantEntry( f_pApiInstance, &pChanEntry->usFlexConfParticipantIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pNewParticipant, pChanEntry->usFlexConfParticipantIndex ); + + /* Reserve an entry for the store event in the mixer memory. */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, f_pusSubStoreEventIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* If using the SOUT port, we must copy this entry */ + if( f_ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + /* Reserve an entry for the copy event in the Mixer memory. */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, f_pusCopyEventIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fCopyEventReserved = TRUE; + + /* Reserve a SIN copy entry if none were reserved before.*/ + if ( pChanEntry->usExtraSinTsiMemIndex == cOCT6100_INVALID_INDEX ) + { + /* Reserve an entry for the extra tsi chariot memory. */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, + &pChanEntry->usExtraSinTsiMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + fExtraSinTsiReserved = TRUE; + } + } + } + else /* if( f_ulInputPort == cOCT6100_CHANNEL_PORT_RIN ) */ + { + /* Reserve a RIN copy entry if none were reserved before.*/ + if ( pChanEntry->usExtraRinTsiMemIndex == cOCT6100_INVALID_INDEX ) + { + /* Reserve an entry for the extra tsi chariot memory. */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, + &pChanEntry->usExtraRinTsiMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + fExtraRinTsiReserved = TRUE; + } + } + + /* Must travel all clients of this conference and reserve a load or accumulate event for */ + /* all participants which can hear us. */ + + /* Search through the list of API channel entry for the ones on to this bridge.*/ + for ( usChannelIndex = 0; ( usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels ) && ( ulResult == cOCT6100_ERR_OK ) ; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + /* Channel reserved? */ + if ( ( usChannelIndex != f_usChanIndex ) && ( pTempEchoChanEntry->fReserved == TRUE ) ) + { + /* On current bridge? */ + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pCurrentParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if we can hear this participant. */ + if ( ( f_ulListenerMask & ( 0x1 << pCurrentParticipant->ulListenerMaskIndex ) ) == 0x0 ) + { + /* Must reserve a load or accumulate entry mixer event here! */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, &pNewParticipant->ausLoadOrAccumulateEventIndex[ pCurrentParticipant->ulListenerMaskIndex ] ); + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Most probably, the hardware is out of mixer events. */ + break; + } + } + + /* Check if this participant can hear us. */ + if ( ( pCurrentParticipant->ulListenerMask & ( 0x1 << f_ulListenerMaskIndex ) ) == 0x0 ) + { + /* Must reserve a load or accumulate entry mixer event here! */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, &pCurrentParticipant->ausLoadOrAccumulateEventIndex[ f_ulListenerMaskIndex ] ); + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Most probably, the hardware is out of mixer events. */ + break; + } + } + } + } + } + + /* If an error is returned, make sure everything is cleaned up properly. */ + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Release the flexible conferencing participant entry. */ + ulTempVar = Oct6100ApiReleaseFlexConfParticipantEntry( f_pApiInstance, pChanEntry->usFlexConfParticipantIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + + pChanEntry->usFlexConfParticipantIndex = cOCT6100_INVALID_INDEX; + + /* Release the substore event in the mixer memory. */ + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, *f_pusSubStoreEventIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + + if ( fCopyEventReserved == TRUE ) + { + /* Release the copy event in the mixer memory. */ + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, *f_pusCopyEventIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fExtraSinTsiReserved == TRUE ) + { + /* Release the extra Sin TSI in TSI memory. */ + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pChanEntry->usExtraSinTsiMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + + pChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + } + + if ( fExtraRinTsiReserved == TRUE ) + { + /* Release the extra Rin TSI in TSI memory. */ + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pChanEntry->usExtraRinTsiMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + + pChanEntry->usExtraRinTsiMemIndex = cOCT6100_INVALID_INDEX; + } + + /* Search through the list of API channel entry for the ones on to this bridge. */ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + /* Channel reserved? */ + if ( ( usChannelIndex != f_usChanIndex ) && ( pTempEchoChanEntry->fReserved == TRUE ) ) + { + /* On current bridge? */ + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pCurrentParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if we can hear this participant. */ + if ( ( f_ulListenerMask & ( 0x1 << pCurrentParticipant->ulListenerMaskIndex ) ) == 0x0 ) + { + /* If the load or event entry in the mixer memory was reserved. */ + if ( pNewParticipant->ausLoadOrAccumulateEventIndex[ pCurrentParticipant->ulListenerMaskIndex ] != cOCT6100_INVALID_INDEX ) + { + /* Must release the load or accumulate entry mixer event. */ + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pNewParticipant->ausLoadOrAccumulateEventIndex[ pCurrentParticipant->ulListenerMaskIndex ] ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + + pNewParticipant->ausLoadOrAccumulateEventIndex[ pCurrentParticipant->ulListenerMaskIndex ] = cOCT6100_INVALID_INDEX; + } + } + + /* Check this participant can hear us. */ + if ( ( pCurrentParticipant->ulListenerMask & ( 0x1 << f_ulListenerMaskIndex ) ) == 0x0 ) + { + /* If the load or event entry in the mixer memory was reserved. */ + if ( pCurrentParticipant->ausLoadOrAccumulateEventIndex[ f_ulListenerMaskIndex ] != cOCT6100_INVALID_INDEX ) + { + /* Must release the load or accumulate entry mixer event. */ + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pCurrentParticipant->ausLoadOrAccumulateEventIndex[ f_ulListenerMaskIndex ] ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + + pCurrentParticipant->ausLoadOrAccumulateEventIndex[ f_ulListenerMaskIndex ] = cOCT6100_INVALID_INDEX; + } + } + } + } + } + + return ulResult; + } + } + else /* if ( ulResult != cOCT6100_ERR_OK ) */ + { + ulTempVar = Oct6100ApiReleaseFlexConfParticipantEntry( f_pApiInstance, pChanEntry->usFlexConfParticipantIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + + pChanEntry->usFlexConfParticipantIndex = cOCT6100_INVALID_INDEX; + + /* Return the error code to the user. The mixer event allocation failed. */ + return ulResult; + } + + /*=======================================================================*/ + } + else /* if ( f_fFlexibleConfBridge == FALSE ) */ + { + /*=======================================================================*/ + /* Normal conferencing. */ + + /* Reserve an entry for the load event in the mixer memory. */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, f_pusLoadEventIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fLoadEventReserved = TRUE; + /* Reserve an entry for the substract and store event in the mixer memory. */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, f_pusSubStoreEventIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fStoreEventReserved = TRUE; + + /* If using the SOUT port, we must copy this entry */ + if( f_ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + /* Reserve an entry for the copy event in the mixer memory. */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, f_pusCopyEventIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fCopyEventReserved = TRUE; + + /* Reserve a SIN copy entry if none were reserved before. */ + if ( pChanEntry->usExtraSinTsiMemIndex == cOCT6100_INVALID_INDEX ) + { + /* Reserve an entry for the extra tsi chariot memory. */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, + &pChanEntry->usExtraSinTsiMemIndex ); + + if ( ulResult == cOCT6100_ERR_OK ) + fExtraSinTsiReserved = TRUE; + } + } + } + } + } + + if ( ( ulResult == cOCT6100_ERR_OK ) && ( f_fTap == TRUE ) ) + { + /* Reserve a "tap" bridge. */ + tOCT6100_CONF_BRIDGE_OPEN ConfBridgeOpen; + UINT32 ulTapBridgeHndl = 0; + + Oct6100ConfBridgeOpenDef( &ConfBridgeOpen ); + + ConfBridgeOpen.pulConfBridgeHndl = &ulTapBridgeHndl; + + ulResult = Oct6100ConfBridgeOpenSer( f_pApiInstance, &ConfBridgeOpen ); + + *f_pusTapBridgeIndex = (UINT16)( ulTapBridgeHndl & cOCT6100_HNDL_INDEX_MASK ); + } + + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( fLoadEventReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, *f_pusLoadEventIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fStoreEventReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, *f_pusSubStoreEventIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fCopyEventReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, *f_pusCopyEventIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fExtraSinTsiReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pChanEntry->usExtraSinTsiMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + + pChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + } + + return ulResult; + } + + /*=======================================================================*/ + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBridgeEventAdd + +Description: Add the event into the global event list of the chip and update + the bridge and channel structures. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to + keep the present state of the chip and all its + resources. +f_usBridgeIndex Index of the current bridge in the API list. +f_usChanIndex Index of the current channel in the API list. +f_fFlexibleConfBridge If this is a flexible conference bridge. +f_usLoadEventIndex Allocated entry for the Load event of the + channel. +f_usSubStoreEventIndex Allocated entry for the substract and store + event of the channel. +f_usCopyEventIndex Allocated entry for the copy event of the + channel. +f_ulInputPort Input port where to copy samples from. +f_fMute Mute flag indicating if the channel is added in + a mute state. +f_ulListenerMaskIndex Index of the listener in this flexible conference bridge. +f_ulListenerMask Mask of listeners in this flexible conference bridge. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBridgeEventAdd +UINT32 Oct6100ApiBridgeEventAdd( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChanIndex, + IN UINT8 f_fFlexibleConfBridge, + IN UINT16 f_usLoadEventIndex, + IN UINT16 f_usSubStoreEventIndex, + IN UINT16 f_usCopyEventIndex, + IN UINT32 f_ulInputPort, + IN UINT8 f_fMute, + IN UINT32 f_ulListenerMaskIndex, + IN UINT32 f_ulListenerMask, + IN UINT8 f_fTap, + IN UINT16 f_usTapBridgeIndex, + IN UINT16 f_usTapChanIndex ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + + tPOCT6100_API_MIXER_EVENT pLoadEventEntry; + tPOCT6100_API_MIXER_EVENT pSubStoreEventEntry; + tPOCT6100_API_MIXER_EVENT pTempEntry; + + tPOCT6100_API_CHANNEL pEchoChanEntry; + tPOCT6100_API_CHANNEL pTapEchoChanEntry = NULL; + tPOCT6100_API_CHANNEL pTempEchoChanEntry; + + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + + UINT32 ulResult; + UINT16 usChannelIndex; + UINT16 usLastSubStoreEventIndex; + UINT16 usLastLoadEventIndex; + + BOOL fAddSinCopy = FALSE; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Get the bridge and channel entries of interest. */ + if ( f_fTap == FALSE ) + { + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( pSharedInfo, pBridgeEntry, f_usBridgeIndex ); + } + else + { + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( pSharedInfo, pBridgeEntry, f_usTapBridgeIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTapEchoChanEntry, f_usTapChanIndex ); + } + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_usChanIndex ); + + if ( f_fFlexibleConfBridge == TRUE ) + { + tPOCT6100_API_FLEX_CONF_PARTICIPANT pNewParticipant; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pCurrentParticipant; + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pNewParticipant, pEchoChanEntry->usFlexConfParticipantIndex ); + + /* Search through the list of API channel entry for the ones onto this bridge. */ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + /* Channel reserved? */ + if ( ( usChannelIndex != f_usChanIndex ) && ( pTempEchoChanEntry->fReserved == TRUE ) ) + { + /* On current bridge? */ + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pCurrentParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if we can hear this participant. */ + if ( ( pTempEchoChanEntry->fMute == FALSE ) && ( ( f_ulListenerMask & ( 0x1 << pCurrentParticipant->ulListenerMaskIndex ) ) == 0x0 ) ) + { + /* First create/update the current channel's mixer. */ + ulResult = Oct6100ApiBridgeAddParticipantToChannel( + f_pApiInstance, + f_usBridgeIndex, + usChannelIndex, + f_usChanIndex, + pNewParticipant->ausLoadOrAccumulateEventIndex[ pCurrentParticipant->ulListenerMaskIndex ], + f_usSubStoreEventIndex, + f_usCopyEventIndex, + pCurrentParticipant->ulInputPort, + f_ulInputPort ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Check if this participant can hear us. */ + if ( ( f_fMute == FALSE ) && ( ( pCurrentParticipant->ulListenerMask & ( 0x1 << f_ulListenerMaskIndex ) ) == 0x0 ) ) + { + /* Then create/update this channel's mixer. */ + ulResult = Oct6100ApiBridgeAddParticipantToChannel( + f_pApiInstance, + f_usBridgeIndex, + f_usChanIndex, + usChannelIndex, + pCurrentParticipant->ausLoadOrAccumulateEventIndex[ f_ulListenerMaskIndex ], + pTempEchoChanEntry->usSubStoreEventIndex, + pTempEchoChanEntry->usSinCopyEventIndex, + f_ulInputPort, + pCurrentParticipant->ulInputPort ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the Rin silence event can be cleared now that the */ + /* channel has been added to a conference. */ + if ( ( pCurrentParticipant->fFlexibleMixerCreated == TRUE ) + && ( pTempEchoChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) ) + { + /* Remove the event from the list. */ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pTempEchoChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pTempEchoChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_DF; + + pTempEchoChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + } + } + } + } + + /* Check if the mixer for the destination channel has been created. */ + if ( pNewParticipant->fFlexibleMixerCreated == FALSE ) + { + /* Save store event index that might be used for next channel added. */ + pEchoChanEntry->usSubStoreEventIndex = f_usSubStoreEventIndex; + } + else + { + /* Check if the Rin silence event can be cleared now that the */ + /* channel has been added to a conference. */ + if ( pEchoChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pEchoChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pEchoChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_DF; + + pEchoChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + } + + pNewParticipant->ulListenerMaskIndex = f_ulListenerMaskIndex; + pNewParticipant->ulListenerMask = f_ulListenerMask; + + /* Remember this channel's input port. */ + pNewParticipant->ulInputPort = f_ulInputPort; + + /*=======================================================================*/ + } + else /* if ( f_fFlexibleConfBridge == FALSE ) */ + { + /* Configure the SIN copy mixer entry and memory - if using the SOUT port. */ + if ( ( f_ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) && ( f_fTap == FALSE ) ) + { + if ( pEchoChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pEchoChanEntry->usSinTsstIndex, + pEchoChanEntry->usExtraSinTsiMemIndex, + pEchoChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* If the silence TSI is loaded on this port, update with the extra sin TSI. */ + if ( pEchoChanEntry->usSinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pEchoChanEntry->usSinSilenceEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pEchoChanEntry->usExtraSinTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLoadEventEntry, f_usLoadEventIndex ); + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pSubStoreEventEntry, f_usSubStoreEventIndex ); + + /*=======================================================================*/ + /* Program the Load event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usLoadEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + if ( ( f_fMute == FALSE ) || ( f_fTap == TRUE ) ) + { + if ( pBridgeEntry->usLoadIndex != cOCT6100_INVALID_INDEX ) + { + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE; + + /* Set the event type. */ + pLoadEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE; + + if ( f_fTap == TRUE ) + return cOCT6100_ERR_FATAL_D1; + } + else /* pBridgeEntry->usLoadIndex == cOCT6100_INVALID_INDEX */ + { + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_LOAD; + + /* Modify the bridge entry to show store the new load index.*/ + pBridgeEntry->usLoadIndex = f_usLoadEventIndex; + + /* Set the event type.*/ + pLoadEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_LOAD; + } + + /* Select the TSI memory index according to the source port. */ + if ( f_ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + if ( f_fTap == FALSE ) + { + WriteParams.usWriteData |= pEchoChanEntry->usSinSoutTsiMemIndex; + } + else + { + tPOCT6100_API_CONF_BRIDGE pTempBridgeEntry; + UINT16 usTempWriteData; + UINT32 ulTempWriteAddress; + + /* Save temp write data before trying to clear the Rin TSST. */ + usTempWriteData = WriteParams.usWriteData; + ulTempWriteAddress = WriteParams.ulWriteAddress; + + /* Clear the Rin TSST if used. */ + if ( pTapEchoChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Deactivate the TSST entry.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( pTapEchoChanEntry->usRinTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Reassign write data that might have been cleared by write above. */ + WriteParams.usWriteData = usTempWriteData; + WriteParams.ulWriteAddress = ulTempWriteAddress; + WriteParams.usWriteData |= pTapEchoChanEntry->usRinRoutTsiMemIndex; + + /* Remember that this channel is being tapped by us. */ + pTapEchoChanEntry->fBeingTapped = TRUE; + pTapEchoChanEntry->usTapChanIndex = f_usChanIndex; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( pSharedInfo, pTempBridgeEntry, f_usBridgeIndex ); + + pTempBridgeEntry->usNumTappedClients++; + } + } + else /* if ( f_ulInputPort == cOCT6100_CHANNEL_PORT_RIN ) */ + { + WriteParams.usWriteData |= pEchoChanEntry->usRinRoutTsiMemIndex; + } + } + else /* f_fMute == TRUE */ + { + /* Do not load the sample if the channel is muted. */ + if ( pBridgeEntry->usNumClients == 0 ) + { + /* If the participant to be added is muted, and it would cause the conference to */ + /* be completely muted, load the silence TSI. */ + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_LOAD; + WriteParams.usWriteData |= 1534; /* TSI index 1534 reserved for silence */ + + /* We know for sure that the load of the bridge will be the silence one. */ + pBridgeEntry->usSilenceLoadEventPtr = f_usLoadEventIndex; + } + else + { + /* Do nothing! */ + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + } + + /* Set the event type. */ + pLoadEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Program the Substract and store event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + if ( ( f_fMute == FALSE ) && ( f_fTap == FALSE ) ) + { + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_SUB_STORE; + /* Select the TSI memory index and PCM law according to the source port. */ + if ( f_ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + WriteParams.usWriteData |= pEchoChanEntry->TdmConfig.bySoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + WriteParams.usWriteData |= pEchoChanEntry->usSinSoutTsiMemIndex; + } + else /* if ( f_ulInputPort == cOCT6100_CHANNEL_PORT_RIN ) */ + { + WriteParams.usWriteData |= pEchoChanEntry->TdmConfig.byRinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + WriteParams.usWriteData |= pEchoChanEntry->usRinRoutTsiMemIndex; + } + + /* Set the event type. */ + pSubStoreEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_SUB_STORE; + } + else /* f_fMute == TRUE */ + { + /* Do not substore the sample if the channel is muted. */ + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_STORE; + + /* Select the PCM law according to the source port. */ + if ( f_ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + WriteParams.usWriteData |= pEchoChanEntry->TdmConfig.bySoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + } + else /* if ( f_ulInputPort == cOCT6100_CHANNEL_PORT_RIN ) */ + { + WriteParams.usWriteData |= pEchoChanEntry->TdmConfig.byRinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + } + /* Set the event type. */ + pSubStoreEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_STORE; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pEchoChanEntry->usRinRoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Program the Copy event - if using the SOUT port */ + if ( ( f_ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) && ( f_fTap == FALSE ) ) + { + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= pEchoChanEntry->usExtraSinTsiMemIndex; + WriteParams.usWriteData |= pEchoChanEntry->TdmConfig.bySinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pEchoChanEntry->usSinSoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set add copy event flag. */ + fAddSinCopy = TRUE; + + /* For sure. */ + pEchoChanEntry->fCopyEventCreated = TRUE; + } + else if ( f_fTap == TRUE ) + { + /* Accumulate the tapped channel's voice instead of building a copy event. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE; + WriteParams.usWriteData |= pTapEchoChanEntry->usSinSoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Link to next operation. */ + WriteParams.ulWriteAddress += 4; + WriteParams.usWriteData = f_usSubStoreEventIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the software model. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, f_usCopyEventIndex ); + + pTempEntry->usSourceChanIndex = f_usTapChanIndex; + pTempEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE; + pTempEntry->usNextEventPtr = f_usSubStoreEventIndex; + pTempEntry->usDestinationChanIndex = cOCT6100_INVALID_INDEX; + pTempEntry->fReserved = TRUE; + } + /*=======================================================================*/ + + /*=======================================================================*/ + /* Now insert the event into the list.*/ + if ( pBridgeEntry->usNumClients == 0 ) + { + /* This is the first entry for this bridge. Insert the two events at the head + of the list just after the last sub-store event.*/ + if ( f_fTap == FALSE ) + { + ulResult = Oct6100ApiGetPrevLastSubStoreEvent( f_pApiInstance, f_usBridgeIndex, pBridgeEntry->usFirstLoadEventPtr, &usLastSubStoreEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_CONF_MIXER_EVENT_NOT_FOUND ) + { + if ( pSharedInfo->MixerInfo.usLastSoutCopyEventPtr == cOCT6100_INVALID_INDEX ) + { + usLastSubStoreEventIndex = cOCT6100_MIXER_HEAD_NODE; + } + else + { + usLastSubStoreEventIndex = pSharedInfo->MixerInfo.usLastSoutCopyEventPtr; + } + } + else + { + return cOCT6100_ERR_FATAL_26; + } + } + } + else + { + if ( pSharedInfo->MixerInfo.usLastSoutCopyEventPtr == cOCT6100_INVALID_INDEX ) + { + usLastSubStoreEventIndex = cOCT6100_MIXER_HEAD_NODE; + } + else + { + usLastSubStoreEventIndex = pSharedInfo->MixerInfo.usLastSoutCopyEventPtr; + } + } + + /* An Entry was found, now, modify it's value.*/ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usLastSubStoreEventIndex ); + + /* Set the Sub-Store event first.*/ + pSubStoreEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_SUB_STORE; + pSubStoreEventEntry->usNextEventPtr = pTempEntry->usNextEventPtr; + + /*=======================================================================*/ + /* Program the Sub-Store event. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + WriteParams.usWriteData = (UINT16)( pSubStoreEventEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Set the load/accumulate event now.*/ + if ( f_fTap == FALSE ) + { + pLoadEventEntry->usNextEventPtr = f_usSubStoreEventIndex; + } + else + { + /* This is a little tricky, we use the copy event index for accumulating the tapped channel's voice. */ + pLoadEventEntry->usNextEventPtr = f_usCopyEventIndex; + } + + /*=======================================================================*/ + /* Program the load/accumulate event. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usLoadEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pLoadEventEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Now modify the previous last Sub Store event from another bridge. */ + pTempEntry->usNextEventPtr = f_usLoadEventIndex; + + /*=======================================================================*/ + /* Modify the last node of the other bridge. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usLastSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pTempEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Set the event pointer info in the bridge stucture. */ + pBridgeEntry->usFirstLoadEventPtr = f_usLoadEventIndex; + pBridgeEntry->usFirstSubStoreEventPtr = f_usSubStoreEventIndex; + pBridgeEntry->usLastSubStoreEventPtr = f_usSubStoreEventIndex; + + /* Update the global mixer pointers. */ + if ( pSharedInfo->MixerInfo.usFirstBridgeEventPtr == cOCT6100_INVALID_INDEX ) + { + /* This bridge is the first to generate mixer event. */ + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = f_usLoadEventIndex; + pSharedInfo->MixerInfo.usLastBridgeEventPtr = f_usSubStoreEventIndex; + } + else if ( pSharedInfo->MixerInfo.usLastBridgeEventPtr == usLastSubStoreEventIndex ) + { + /* The two entries were added at the end of the bridge section, */ + /* change only the last pointer. */ + pSharedInfo->MixerInfo.usLastBridgeEventPtr = f_usSubStoreEventIndex; + } + else if ( usLastSubStoreEventIndex == cOCT6100_MIXER_HEAD_NODE || + usLastSubStoreEventIndex == pSharedInfo->MixerInfo.usLastSoutCopyEventPtr ) + { + /* The two entries were added at the start of the bridge section, */ + /* change only the first pointer. */ + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = f_usLoadEventIndex; + } + } + else /* pBridgeEntry->usNumClients != 0 */ + { + /* For sanity. */ + if ( f_fTap == TRUE ) + return cOCT6100_ERR_FATAL_D2; + + /*=======================================================================*/ + /* Program the Load event. */ + + /* Now find the last load entry of this bridge. */ + ulResult = Oct6100ApiGetPreviousEvent( f_pApiInstance, pBridgeEntry->usFirstLoadEventPtr, pBridgeEntry->usFirstSubStoreEventPtr, 0, &usLastLoadEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Add the load/accumulate event to the list. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usLastLoadEventIndex ); + + /* Set the load event now. */ + pLoadEventEntry->usNextEventPtr = pTempEntry->usNextEventPtr; + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usLoadEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pLoadEventEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Modify the previous last load event. */ + + /* Now modify the previous last load event. */ + pTempEntry->usNextEventPtr = f_usLoadEventIndex; + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usLastLoadEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pTempEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Program the Sub-Store event. */ + + usLastSubStoreEventIndex = pBridgeEntry->usLastSubStoreEventPtr; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usLastSubStoreEventIndex ); + + /* Set the Sub-Store event first. */ + pSubStoreEventEntry->usNextEventPtr = pTempEntry->usNextEventPtr; + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pSubStoreEventEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Modify the previous last sub store event of the bridge. */ + + /* Now modify the last Load event of the bridge. */ + pTempEntry->usNextEventPtr = f_usSubStoreEventIndex; + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usLastSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pTempEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Update the bridge pointers. */ + pBridgeEntry->usLastSubStoreEventPtr = f_usSubStoreEventIndex; + + /* Check if modification to the global mixer pointer are required. */ + if ( pSharedInfo->MixerInfo.usLastBridgeEventPtr == usLastSubStoreEventIndex ) + { + /* We have a new last bridge pointer. */ + pSharedInfo->MixerInfo.usLastBridgeEventPtr = f_usSubStoreEventIndex; + } + } + + if ( f_fTap == TRUE ) + { + if ( pEchoChanEntry->usRinTsstIndex == cOCT6100_INVALID_INDEX ) + { + /* Remove the mute on the Rin port. */ + + UINT32 ulTempData; + UINT32 ulMask; + UINT32 ulBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_usChanIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + + /* Configure the level control. */ + + UINT32 ulFeatureBytesOffset = pSharedInfo->MemoryMap.RinLevelControlOfst.usDwordOffset * 4; + UINT32 ulFeatureBitOffset = pSharedInfo->MemoryMap.RinLevelControlOfst.byBitOffset; + UINT32 ulFeatureFieldLength = pSharedInfo->MemoryMap.RinLevelControlOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pEchoChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set the DC filter to pass through.*/ + ulTempData |= ( cOCT6100_PASS_THROUGH_LEVEL_CONTROL << ulFeatureBitOffset ); + + /* First read the DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the event entries as reserved. */ + pLoadEventEntry->fReserved = TRUE; + pSubStoreEventEntry->fReserved = TRUE; + + /* Store the event indexes into the channel structure. */ + pEchoChanEntry->usLoadEventIndex = f_usLoadEventIndex; + pEchoChanEntry->usSubStoreEventIndex = f_usSubStoreEventIndex; + + /* Check if must insert the Sin copy event in the list. */ + if ( fAddSinCopy == TRUE ) + { + /* Now insert the Sin copy event into the list. */ + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_usCopyEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY, + f_usChanIndex ); + } + + /* Check if the Rin silence event can be cleared now that the */ + /* channel has been added to a conference. */ + if ( ( f_fTap == FALSE ) && ( pEchoChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) ) + { + /* Remove the event from the list. */ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pEchoChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pEchoChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_DF; + + pEchoChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + } + + /* Configure the RIN copy mixer entry and memory - if using the RIN port. */ + if ( ( f_fFlexibleConfBridge == TRUE ) && ( f_ulInputPort == cOCT6100_CHANNEL_PORT_RIN ) ) + { + if ( pEchoChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pEchoChanEntry->usRinTsstIndex, + pEchoChanEntry->usExtraRinTsiMemIndex, + pEchoChanEntry->TdmConfig.byRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + if ( pBridgeEntry->fDominantSpeakerSet == TRUE ) + { + /* Dominant speaker is another channel. Set accordingly for this new conference channel. */ + ulResult = Oct6100ApiBridgeSetDominantSpeaker( f_pApiInstance, f_usChanIndex, pBridgeEntry->usDominantSpeakerChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + /* No dominant speaker set on this bridge yet. */ + ulResult = Oct6100ApiBridgeSetDominantSpeaker( f_pApiInstance, f_usChanIndex, cOCT6100_CONF_DOMINANT_SPEAKER_UNASSIGNED ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Update the bridge entry. */ + pBridgeEntry->usNumClients++; + + /* Store the bridge index into the channel structure. */ + pEchoChanEntry->usBridgeIndex = f_usBridgeIndex; + + /* Store the copy event index into the channel structure. */ + if ( f_ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + pEchoChanEntry->usSinCopyEventIndex = f_usCopyEventIndex; + } + else + { + pEchoChanEntry->usSinCopyEventIndex = cOCT6100_INVALID_INDEX; + } + + /* Remember if the channel is muted in the conference. */ + pEchoChanEntry->fMute = f_fMute; + + /* Remember if the channel is a tap in a conference. */ + pEchoChanEntry->fTap = f_fTap; + + /* We start by not being tapped. */ + pEchoChanEntry->fBeingTapped = FALSE; + pEchoChanEntry->usTapChanIndex = cOCT6100_INVALID_INDEX; + + /* Remember the tap bridge index if necessary. */ + if ( pEchoChanEntry->fTap == TRUE ) + { + pEchoChanEntry->usTapBridgeIndex = f_usTapBridgeIndex; + } + else + { + pEchoChanEntry->usTapBridgeIndex = cOCT6100_INVALID_INDEX; + } + + /* Indicate that the extra SIN TSI is currently in used by the conference bridge. */ + if ( f_ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + pEchoChanEntry->usExtraSinTsiDependencyCnt++; + } + + /* Indicate that the extra RIN TSI is currently in used by the conference bridge. */ + if ( ( f_fFlexibleConfBridge == TRUE ) && ( f_ulInputPort == cOCT6100_CHANNEL_PORT_RIN ) ) + { + pEchoChanEntry->usExtraRinTsiDependencyCnt++; + } + + /* Update the chip stats structure. */ + pSharedInfo->ChipStats.usNumEcChanUsingMixer++; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBridgeAddParticipantToChannel + +Description: Used for the flexible conference bridges. Insert a participant + onto a channel that is on a conference. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_usBridgeIndex Bridge index where this channel is located. +f_usSourceChannelIndex Source channel to copy voice from. +f_usDestinationChannelIndex Destination channel to store resulting voice to. +f_usLoadOrAccumulateEventIndex Load or Accumulate allocated event index. +f_usStoreEventIndex Store allocated event index. +f_usCopyEventIndex Copy allocated event index. +f_ulSourceInputPort Source input port of the conference for this channel. +f_ulDestinationInputPort Destination input port of the conference for this channel. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBridgeAddParticipantToChannel +UINT32 Oct6100ApiBridgeAddParticipantToChannel( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usSourceChannelIndex, + IN UINT16 f_usDestinationChannelIndex, + IN UINT16 f_usLoadOrAccumulateEventIndex, + IN UINT16 f_usStoreEventIndex, + IN UINT16 f_usCopyEventIndex, + IN UINT32 f_ulSourceInputPort, + IN UINT32 f_ulDestinationInputPort ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + + tPOCT6100_API_MIXER_EVENT pLoadEventEntry; + tPOCT6100_API_MIXER_EVENT pStoreEventEntry; + tPOCT6100_API_MIXER_EVENT pTempEntry; + + tPOCT6100_API_CHANNEL pSourceChanEntry; + tPOCT6100_API_CHANNEL pDestinationChanEntry; + + tPOCT6100_API_FLEX_CONF_PARTICIPANT pDestinationParticipant; + + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + + UINT32 ulResult; + UINT16 usLastSubStoreEventIndex; + UINT16 usLastLoadEventIndex; + BOOL fInsertCopy = FALSE; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, f_usBridgeIndex ); + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pSourceChanEntry, f_usSourceChannelIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pDestinationChanEntry, f_usDestinationChannelIndex ); + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pDestinationParticipant, pDestinationChanEntry->usFlexConfParticipantIndex ); + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLoadEventEntry, f_usLoadOrAccumulateEventIndex ); + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pStoreEventEntry, f_usStoreEventIndex ); + + /* Check if we are creating the first event for this channel. */ + if ( pDestinationParticipant->fFlexibleMixerCreated == FALSE ) + { + /*=======================================================================*/ + /* Before creating the participant's flexible mixer, make sure the extra Sin */ + /* mixer event is programmed correctly for sending the voice stream to the right place. */ + + /* Configure the SIN copy mixer entry and memory - if using the SOUT port. */ + if ( f_ulDestinationInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + if ( pDestinationChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pDestinationChanEntry->usSinTsstIndex, + pDestinationChanEntry->usExtraSinTsiMemIndex, + pDestinationChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* If the silence TSI is loaded on this port, update with the extra sin TSI. */ + if ( pDestinationChanEntry->usSinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pDestinationChanEntry->usSinSilenceEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pDestinationChanEntry->usExtraSinTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Program the load event. This is the first event for this new destination channel. */ + + /* First set the TSI buffer where the resulting stream should be written to. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usLoadOrAccumulateEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + /* For sure, we are loading. */ + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_LOAD; + + /* Select the TSI memory index according to the source port. */ + if ( f_ulSourceInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + WriteParams.usWriteData |= pSourceChanEntry->usSinSoutTsiMemIndex; + } + else /* if ( f_ulSourceInputPort == cOCT6100_CHANNEL_PORT_RIN ) */ + { + WriteParams.usWriteData |= pSourceChanEntry->usExtraRinTsiMemIndex; + } + + /* Set the event type. */ + pLoadEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_LOAD; + + /* Set the source channel index. */ + pLoadEventEntry->usSourceChanIndex = f_usSourceChannelIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + + /*=======================================================================*/ + /* Program the store event. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_STORE; + + /* Select the TSI memory index and PCM law according to the source port. */ + if ( f_ulDestinationInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + WriteParams.usWriteData |= pDestinationChanEntry->TdmConfig.bySoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + WriteParams.usWriteData |= pDestinationChanEntry->usSinSoutTsiMemIndex; + } + else /* if ( f_ulDestinationInputPort == cOCT6100_CHANNEL_PORT_RIN ) */ + { + WriteParams.usWriteData |= pDestinationChanEntry->TdmConfig.byRinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + WriteParams.usWriteData |= pDestinationChanEntry->usRinRoutTsiMemIndex; + } + + /* Set the event type. */ + pStoreEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_STORE; + + /* Set the destination channel index. */ + pStoreEventEntry->usDestinationChanIndex = f_usDestinationChannelIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pDestinationChanEntry->usRinRoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + + /*=======================================================================*/ + /* Program the Copy event - if using the SOUT port */ + + if ( ( f_ulDestinationInputPort == cOCT6100_CHANNEL_PORT_SOUT ) && ( pDestinationChanEntry->fCopyEventCreated == FALSE ) ) + { + /* The copy event has not been created, create it once for the life of the participant on the bridge. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= pDestinationChanEntry->usExtraSinTsiMemIndex; + WriteParams.usWriteData |= pDestinationChanEntry->TdmConfig.bySinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pDestinationChanEntry->usSinSoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + pDestinationChanEntry->fCopyEventCreated = TRUE; + + /* Set insert copy flag. */ + fInsertCopy = TRUE; + } + + /*=======================================================================*/ + + + + /*=======================================================================*/ + /*=======================================================================*/ + /* Now, insert the events into the current list. */ + /*=======================================================================*/ + /*=======================================================================*/ + + /* This is the first entry for this channel. Insert the two events at the head */ + /* of the list just after the last Sub-Store or Store event. */ + ulResult = Oct6100ApiGetPrevLastSubStoreEvent( f_pApiInstance, f_usBridgeIndex, f_usLoadOrAccumulateEventIndex, &usLastSubStoreEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_CONF_MIXER_EVENT_NOT_FOUND ) + { + if ( pSharedInfo->MixerInfo.usLastSoutCopyEventPtr == cOCT6100_INVALID_INDEX ) + { + usLastSubStoreEventIndex = cOCT6100_MIXER_HEAD_NODE; + } + else + { + usLastSubStoreEventIndex = pSharedInfo->MixerInfo.usLastSoutCopyEventPtr; + } + } + else + { + return cOCT6100_ERR_FATAL_26; + } + } + + /* An entry was found, now, modify it's value. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usLastSubStoreEventIndex ); + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Link the store event first. */ + + pStoreEventEntry->usNextEventPtr = pTempEntry->usNextEventPtr; + + /* Link the store event. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + WriteParams.usWriteData = (UINT16)( pStoreEventEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Link the load event now.*/ + + pLoadEventEntry->usNextEventPtr = f_usStoreEventIndex; + + /* Link the load event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usLoadOrAccumulateEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pLoadEventEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Now modify the previous last Sub-Store or Store event from another bridge, */ + /* such that it links to us. */ + + pTempEntry->usNextEventPtr = f_usLoadOrAccumulateEventIndex; + + /* Modify the last node of the other bridge. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usLastSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pTempEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Set the event pointer info in the bridge stucture. */ + + if ( pBridgeEntry->usFirstLoadEventPtr == cOCT6100_INVALID_INDEX ) + { + /* We only do this once in case of the flexible conference bridges. */ + pBridgeEntry->usFirstLoadEventPtr = f_usLoadOrAccumulateEventIndex; + pBridgeEntry->usFirstSubStoreEventPtr = f_usStoreEventIndex; + } + + pBridgeEntry->usLastSubStoreEventPtr = f_usStoreEventIndex; + + /* Update the global mixer pointers. */ + if ( pSharedInfo->MixerInfo.usFirstBridgeEventPtr == cOCT6100_INVALID_INDEX ) + { + /* This bridge is the first to generate mixer event. */ + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = f_usLoadOrAccumulateEventIndex; + pSharedInfo->MixerInfo.usLastBridgeEventPtr = f_usStoreEventIndex; + } + else if ( pSharedInfo->MixerInfo.usLastBridgeEventPtr == usLastSubStoreEventIndex ) + { + /* The two entries were added at the end of the bridge section, */ + /* change only the last pointer. */ + pSharedInfo->MixerInfo.usLastBridgeEventPtr = f_usStoreEventIndex; + } + else if ( usLastSubStoreEventIndex == cOCT6100_MIXER_HEAD_NODE || + usLastSubStoreEventIndex == pSharedInfo->MixerInfo.usLastSoutCopyEventPtr ) + { + /* The two entries were added at the start of the bridge section, */ + /* change only the first pointer.*/ + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = f_usLoadOrAccumulateEventIndex; + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Insert the copy event if needed in the mixer's list. */ + + if ( fInsertCopy == TRUE ) + { + /* Now insert the Sin copy event into the list. */ + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_usCopyEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY, + f_usDestinationChannelIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Update the status of the instance structures. */ + + pDestinationParticipant->fFlexibleMixerCreated = TRUE; + + /* Set the event entries as reserved. */ + pLoadEventEntry->fReserved = TRUE; + pStoreEventEntry->fReserved = TRUE; + + /* Store the event indexes into the channel structure. */ + pDestinationChanEntry->usLoadEventIndex = f_usLoadOrAccumulateEventIndex; + pDestinationChanEntry->usSubStoreEventIndex = f_usStoreEventIndex; + + /*=======================================================================*/ + } + else /* if ( pDestinationChanEntry->fFlexibleMixerCreated == TRUE ) */ + { + /*=======================================================================*/ + /* Program the Accumulate event. */ + + /* First set the TSI buffer where the resulting stream should be written to. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usLoadOrAccumulateEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + /* For sure, we are accumulating. */ + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE; + + /* Select the TSI memory index according to the source port. */ + if ( f_ulSourceInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + WriteParams.usWriteData |= pSourceChanEntry->usSinSoutTsiMemIndex; + } + else /* if ( f_ulSourceInputPort == cOCT6100_CHANNEL_PORT_RIN ) */ + { + WriteParams.usWriteData |= pSourceChanEntry->usExtraRinTsiMemIndex; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + + /*=======================================================================*/ + /*=======================================================================*/ + /* Now, insert the Accumulate event into the current list. */ + /*=======================================================================*/ + /*=======================================================================*/ + + /* Use the Load entry of this channel. */ + usLastLoadEventIndex = pDestinationChanEntry->usLoadEventIndex; + + /* Add the Accumulate event to the list. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usLastLoadEventIndex ); + + /* Set the accumulate event now. */ + pLoadEventEntry->usNextEventPtr = pTempEntry->usNextEventPtr; + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usLoadOrAccumulateEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pLoadEventEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + + /*=======================================================================*/ + /* Modify the previous Load event. */ + + /* Now modify the previous Load event. */ + pTempEntry->usNextEventPtr = f_usLoadOrAccumulateEventIndex; + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usLastLoadEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pTempEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + + /*=======================================================================*/ + /* Update the status of the instance structures. */ + + /* Set the Accumulate event entry as reserved. */ + pLoadEventEntry->fReserved = TRUE; + /* Set the Event type. */ + pLoadEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE; + /* Set the source channel index. */ + pLoadEventEntry->usSourceChanIndex = f_usSourceChannelIndex; + + /*=======================================================================*/ + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeChanRemoveSer + +Description: Removes an echo channel from a conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeRemove Pointer to conference bridge channel remove structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeChanRemoveSer +UINT32 Oct6100ConfBridgeChanRemoveSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove ) +{ + UINT16 usBridgeIndex; + UINT16 usChanIndex = 0; + UINT16 usLoadEventIndex; + UINT16 usSubStoreEventIndex; + UINT16 usCopyEventIndex; + UINT32 ulResult; + UINT8 fFlexibleConfBridge; + UINT8 fTap; + + /* Check the validity of the channel and conference bridge given. */ + ulResult = Oct6100ApiCheckChanRemoveParams( + f_pApiInstance, + f_pConfBridgeRemove, + &usBridgeIndex, + &usChanIndex, + &fFlexibleConfBridge, + &fTap, + &usLoadEventIndex, + &usSubStoreEventIndex, + &usCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources reserved for the conference bridge. */ + ulResult = Oct6100ApiReleaseChanEventResources( + f_pApiInstance, + f_pConfBridgeRemove, + usBridgeIndex, + usChanIndex, + fFlexibleConfBridge, + usLoadEventIndex, + usSubStoreEventIndex, + usCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear the memory entry for this channel within the bridge. */ + ulResult = Oct6100ApiBridgeEventRemove( + f_pApiInstance, + f_pConfBridgeRemove, + usBridgeIndex, + usChanIndex, + fFlexibleConfBridge, + usLoadEventIndex, + usSubStoreEventIndex, + usCopyEventIndex, + fTap ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckChanRemoveParams + +Description: Check the validity of the channel and conference bridge given. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_pConfBridgeRemove Pointer to conference bridge channenl add structure. +f_pusBridgeIndex Pointer to the bridge index. +f_pfFlexibleConfBridge If this is a flexible conference bridge +f_pusChannelIndex Pointer to the channel index to be added to the bridge. +f_pusLoadEventIndex Pointer to the load mixer event. +f_pusSubStoreEventIndex Pointer to the sub-store mixer event. +f_pusCopyEventIndex Pointer to the copy mixer event. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckChanRemoveParams +UINT32 Oct6100ApiCheckChanRemoveParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove, + OUT PUINT16 f_pusBridgeIndex, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT8 f_pfFlexibleConfBridge, + OUT PUINT8 f_pfTap, + OUT PUINT16 f_pusLoadEventIndex, + OUT PUINT16 f_pusSubStoreEventIndex, + OUT PUINT16 f_pusCopyEventIndex ) +{ + UINT32 ulEntryOpenCnt; + tPOCT6100_API_CHANNEL pEchoChanEntry; + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + + /* Verify if the remove all flag is valid. */ + if ( f_pConfBridgeRemove->fRemoveAll != TRUE && + f_pConfBridgeRemove->fRemoveAll != FALSE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_REMOVE_ALL; + + /* Check the channel handle only if the remove all flag is set to FALSE. */ + if ( f_pConfBridgeRemove->fRemoveAll == FALSE ) + { + /*=====================================================================*/ + /* Check the channel handle. */ + + if ( (f_pConfBridgeRemove->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + *f_pusChannelIndex = (UINT16)( f_pConfBridgeRemove->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChanEntry, *f_pusChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeRemove->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + if ( pEchoChanEntry->fBeingTapped == TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_DEPENDENCY; + + /*=====================================================================*/ + + *f_pusBridgeIndex = pEchoChanEntry->usBridgeIndex; + *f_pusLoadEventIndex = pEchoChanEntry->usLoadEventIndex; + *f_pusSubStoreEventIndex = pEchoChanEntry->usSubStoreEventIndex; + *f_pusCopyEventIndex = pEchoChanEntry->usSinCopyEventIndex; + + /* Check if the channel is really part of the bridge. */ + if ( *f_pusBridgeIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHAN_NOT_ON_BRIDGE; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, *f_pusBridgeIndex ) + + /* Return whether this is a flexible bridge or not. */ + *f_pfFlexibleConfBridge = pBridgeEntry->fFlexibleConferencing; + + /* Return whether this is a tap or not. */ + *f_pfTap = pEchoChanEntry->fTap; + } + else /* f_pConfBridgeRemove->fRemoveAll == TRUE */ + { + /* Check the provided handle. */ + if ( (f_pConfBridgeRemove->ulConfBridgeHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CONF_BRIDGE ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + *f_pusBridgeIndex = (UINT16)( f_pConfBridgeRemove->ulConfBridgeHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusBridgeIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, *f_pusBridgeIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeRemove->ulConfBridgeHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pBridgeEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( ulEntryOpenCnt != pBridgeEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + /* This information is not currently available. */ + *f_pusLoadEventIndex = cOCT6100_INVALID_INDEX; + *f_pusSubStoreEventIndex = cOCT6100_INVALID_INDEX; + *f_pusCopyEventIndex = cOCT6100_INVALID_INDEX; + + /* Return whether this is a flexible bridge or not. */ + *f_pfFlexibleConfBridge = pBridgeEntry->fFlexibleConferencing; + + *f_pfTap = FALSE; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseChanEventResources + +Description: Release all resources reserved to the channel part of the + conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_pConfBridgeRemove Pointer to conference bridge channel add structure. +f_usBridgeIndex Index of the bridge structure within the API's bridge list. +f_usChanIndex Index of the channel structure within the API's channel list +f_fFlexibleConfBridge If this is a flexible conference bridge. +f_usLoadEventIndex Index of the load mixer event. +f_usSubStoreEventIndex Index of the sub-store mixer event. +f_usCopyEventIndex Index of the copy mixer event. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseChanEventResources +UINT32 Oct6100ApiReleaseChanEventResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChanIndex, + IN UINT8 f_fFlexibleConfBridge, + IN UINT16 f_usLoadEventIndex, + IN UINT16 f_usSubStoreEventIndex, + IN UINT16 f_usCopyEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pEchoChanEntry; + UINT32 ulResult; + UINT32 i; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + if ( f_fFlexibleConfBridge == TRUE ) + { + tPOCT6100_API_FLEX_CONF_PARTICIPANT pParticipant; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pTempParticipant; + + if ( f_pConfBridgeRemove->fRemoveAll == FALSE ) + { + tPOCT6100_API_CHANNEL pTempEchoChanEntry; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_usChanIndex ); + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pParticipant, pEchoChanEntry->usFlexConfParticipantIndex ); + + /* Release an entry for the store event in the mixer memory. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, f_usSubStoreEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + /* Release an entry for the Sin copy event in the mixer memory. */ + /* This value can be invalid if the Rin port was used - no need to release. */ + if ( f_usCopyEventIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, f_usCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + } + + /* This value can be 0 if the Rin port was used - no need to release. */ + if ( pEchoChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + /* Release the extra TSI entry.*/ + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pEchoChanEntry->usExtraSinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + } + + /* This value can be 0 if the Sout port was used - no need to release. */ + if ( pEchoChanEntry->usExtraRinTsiDependencyCnt == 1 ) + { + /* Release the extra TSI entry.*/ + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pEchoChanEntry->usExtraRinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + } + + /* Must travel all clients of this conference and release the load or accumulate events for */ + /* all participants which can hear us and vice versa. */ + + /* Search through the list of API channel entry for the ones on to this bridge. */ + for ( i = 0; ( i < pSharedInfo->ChipConfig.usMaxChannels ) && ( ulResult == cOCT6100_ERR_OK ); i++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, i ); + + /* Channel reserved? */ + if ( ( i != f_usChanIndex ) && pTempEchoChanEntry->fReserved == TRUE ) + { + /* On current bridge? */ + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if we can hear this participant. */ + if ( ( pParticipant->ulListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) == 0x0 ) + { + /* Must release the allocated mixer event. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ] ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ] = cOCT6100_INVALID_INDEX; + } + + /* Check if this participant can hear us. */ + if ( ( pTempParticipant->ulListenerMask & ( 0x1 << pParticipant->ulListenerMaskIndex ) ) == 0x0 ) + { + /* Must release the allocated mixer event. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pTempParticipant->ausLoadOrAccumulateEventIndex[ pParticipant->ulListenerMaskIndex ] ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + pTempParticipant->ausLoadOrAccumulateEventIndex[ pParticipant->ulListenerMaskIndex ] = cOCT6100_INVALID_INDEX; + } + } + } + } + } + else /* f_pConfBridgeRemove->fRemoveAll == TRUE */ + { + UINT32 ulListenerMaskIndex; + + ulResult = cOCT6100_ERR_OK; + + /* Search through the list of API channel entry for the ones on to this bridge.*/ + for ( i = 0; ( i < pSharedInfo->ChipConfig.usMaxChannels ) && ( ulResult == cOCT6100_ERR_OK ); i++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, i ); + + /* Channel reserved? */ + if ( pEchoChanEntry->fReserved == TRUE ) + { + /* On current bridge? */ + if ( pEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pParticipant, pEchoChanEntry->usFlexConfParticipantIndex ); + + /* Release an entry for the Store event in the Mixer memory. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pEchoChanEntry->usSubStoreEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + /* Release an entry for the Sin copy event in the Mixer memory. */ + /* This value can be invalid if the Rin port was used - no need to release. */ + if ( pEchoChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pEchoChanEntry->usSinCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + } + + /* This value can be 0 if the Rin port was used - no need to release. */ + if ( pEchoChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + /* Release the extra TSI entry.*/ + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pEchoChanEntry->usExtraSinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + } + + /* This value can be 0 if the Sout port was used - no need to release. */ + if ( pEchoChanEntry->usExtraRinTsiDependencyCnt == 1 ) + { + /* Release the extra TSI entry.*/ + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pEchoChanEntry->usExtraRinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + } + + /* Check if something can be freed. */ + for ( ulListenerMaskIndex = 0; ulListenerMaskIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulListenerMaskIndex ++ ) + { + if ( pParticipant->ausLoadOrAccumulateEventIndex[ ulListenerMaskIndex ] != cOCT6100_INVALID_INDEX ) + { + /* Must release the allocated mixer event. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pParticipant->ausLoadOrAccumulateEventIndex[ ulListenerMaskIndex ] ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + pParticipant->ausLoadOrAccumulateEventIndex[ ulListenerMaskIndex ] = cOCT6100_INVALID_INDEX; + } + } + } + } + } + + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else /* if ( f_fFlexibleConfBridge == FALSE ) */ + { + if ( f_pConfBridgeRemove->fRemoveAll == FALSE ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_usChanIndex ); + + /* Release the entry for the load event in the mixer memory. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, f_usLoadEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + /* Release an entry for the substract and store event in the mixer memory. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, f_usSubStoreEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + /* Release an entry for the Sin copy event in the Mixer memory. */ + /* This value can be invalid if the Rin port was used - no need to release. */ + if ( f_usCopyEventIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, f_usCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + } + + /* This value can be 0 if the Rin port was used - no need to release. */ + if ( pEchoChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + /* Release the extra TSI entry. */ + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pEchoChanEntry->usExtraSinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + } + } + else /* f_pConfBridgeRemove->fRemoveAll == TRUE */ + { + /* Search through the list of API channel entry for the ones on to the specified bridge.*/ + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxChannels; i++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, i ); + + if ( pEchoChanEntry->fReserved == TRUE ) + { + if ( ( pEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) && ( pEchoChanEntry->fTap == FALSE ) ) + { + /* Release the entry for the load event in the mixer memory. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, + pEchoChanEntry->usLoadEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + /* Release an entry for the substract and store event in the Mixer memory. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, + pEchoChanEntry->usSubStoreEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + /* Release an entry for the Sin copy event in the Mixer memory. */ + /* This value can be invalid if the Rin port was used - no need to release. */ + if ( pEchoChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, + pEchoChanEntry->usSinCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + } + + /* This value can be 0 if the Rin port was used - no need to release. */ + if ( pEchoChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + /* Release the extra TSI entry.*/ + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pEchoChanEntry->usExtraSinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + } + } + } + } + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBridgeEventRemove + +Description: Remove the event from the global event list of the chip and + update the bridge and channel structures. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_pConfBridgeRemove Pointer to a conference bridge channel remove structure. +f_usBridgeIndex Index of the current bridge in the API list. +f_usChanIndex Index of the current channel in the API list. +f_fFlexibleConfBridge If this is a flexible conference bridge. +f_usLoadEventIndex Allocated entry for the Load event of the channel. +f_usSubStoreEventIndex Allocated entry for the substract and store event of the channel. +f_usCopyEventIndex Allocated entry for the copy event of the channel. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBridgeEventRemove +UINT32 Oct6100ApiBridgeEventRemove ( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChanIndex, + IN UINT8 f_fFlexibleConfBridge, + IN UINT16 f_usLoadEventIndex, + IN UINT16 f_usSubStoreEventIndex, + IN UINT16 f_usCopyEventIndex, + IN UINT8 f_fTap ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + + tPOCT6100_API_MIXER_EVENT pLoadEventEntry; + tPOCT6100_API_MIXER_EVENT pSubStoreEventEntry; + tPOCT6100_API_MIXER_EVENT pCopyEventEntry = NULL; + tPOCT6100_API_MIXER_EVENT pTempEntry; + + tPOCT6100_API_CHANNEL pEchoChanEntry; + tPOCT6100_API_CHANNEL pTempEchoChanEntry; + + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + + UINT32 ulResult; + UINT16 usPreviousEventIndex; + UINT16 usTempEventIndex; + UINT32 ulLoopCount = 0; + UINT16 usReadData; + UINT16 usChannelIndex; + UINT32 i; + + BOOL fRemoveSinCopy = FALSE; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( pSharedInfo, pBridgeEntry, f_usBridgeIndex ); + + /* If no client on the bridge, and the remove all option is specified, return here. */ + if ( ( pBridgeEntry->usNumClients == 0 ) && ( f_pConfBridgeRemove->fRemoveAll == TRUE ) ) + return cOCT6100_ERR_OK; + + /* Make sure the dominant speaker feature is disabled first. */ + if ( pBridgeEntry->fDominantSpeakerSet == TRUE ) + { + /* If all channels are to be removed or if the dominant speaker is the current channel to be removed. */ + if ( ( f_pConfBridgeRemove->fRemoveAll == TRUE ) + || ( ( f_pConfBridgeRemove->fRemoveAll == FALSE ) && ( pBridgeEntry->usDominantSpeakerChanIndex == f_usChanIndex ) ) ) + { + /* Disable on all channels part of this conference. */ + + /* Search through the list of API channel entry for the ones on to this bridge. */ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + if ( pTempEchoChanEntry->fReserved == TRUE ) + { + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + ulResult = Oct6100ApiBridgeSetDominantSpeaker( f_pApiInstance, usChannelIndex, cOCT6100_CONF_DOMINANT_SPEAKER_UNASSIGNED ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Save this in the conference bridge structure. */ + pBridgeEntry->fDominantSpeakerSet = FALSE; + pBridgeEntry->usDominantSpeakerChanIndex = cOCT6100_INVALID_INDEX; + } + else + { + /* Only disable this current channel. */ + ulResult = Oct6100ApiBridgeSetDominantSpeaker( f_pApiInstance, f_usChanIndex, cOCT6100_CONF_DOMINANT_SPEAKER_UNASSIGNED ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + if ( f_fFlexibleConfBridge == TRUE ) + { + tPOCT6100_API_FLEX_CONF_PARTICIPANT pParticipant; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pTempParticipant; + UINT16 ausMutePortChannelIndexes[ cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE ]; + UINT32 ulMutePortChannelIndex; + + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + ausMutePortChannelIndexes[ ulMutePortChannelIndex ] = cOCT6100_INVALID_INDEX; + + if ( f_pConfBridgeRemove->fRemoveAll == FALSE ) + { + /* The channel index is valid. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_usChanIndex ); + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pParticipant, pEchoChanEntry->usFlexConfParticipantIndex ); + + /* Search through the list of API channel entry for the ones on to this bridge. */ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + if ( ( usChannelIndex != f_usChanIndex ) && ( pTempEchoChanEntry->fReserved == TRUE ) ) + { + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if we can hear this participant. */ + if ( ( ( pParticipant->ulListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) == 0x0 ) + && ( pParticipant->fFlexibleMixerCreated == TRUE ) + && ( pTempEchoChanEntry->fMute == FALSE ) ) + { + /* First update the current channel's mixer. */ + ulResult = Oct6100ApiBridgeRemoveParticipantFromChannel( + f_pApiInstance, + f_usBridgeIndex, + usChannelIndex, + f_usChanIndex, + TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Check if this participant can hear us. */ + if ( ( ( pTempParticipant->ulListenerMask & ( 0x1 << pParticipant->ulListenerMaskIndex ) ) == 0x0 ) + && ( pTempParticipant->fFlexibleMixerCreated == TRUE ) + && ( pEchoChanEntry->fMute == FALSE ) ) + { + /* Then update this channel's mixer. */ + ulResult = Oct6100ApiBridgeRemoveParticipantFromChannel( + f_pApiInstance, + f_usBridgeIndex, + f_usChanIndex, + usChannelIndex, + TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Remember to mute the port on this channel. */ + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + { + if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == usChannelIndex ) + { + break; + } + else if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == cOCT6100_INVALID_INDEX ) + { + ausMutePortChannelIndexes[ ulMutePortChannelIndex ] = usChannelIndex; + break; + } + } + } + } + } + } + + /* Check if must manually clear the Sin copy event. */ + if ( ( pEchoChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) + && ( pEchoChanEntry->fCopyEventCreated == TRUE ) ) + { + /* Transform event into no-operation. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pEchoChanEntry->usSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now remove the copy event from the event list. */ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, pEchoChanEntry->usSinCopyEventIndex, cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + pEchoChanEntry->fCopyEventCreated = FALSE; + } + + /* Release an entry for the participant. */ + ulResult = Oct6100ApiReleaseFlexConfParticipantEntry( f_pApiInstance, pEchoChanEntry->usFlexConfParticipantIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + /*=======================================================================*/ + /* Update the event and channel API structure */ + pEchoChanEntry->usFlexConfParticipantIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usBridgeIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usLoadEventIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usSubStoreEventIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usSinCopyEventIndex = cOCT6100_INVALID_INDEX; + + /* Indicate that the extra SIN TSI is not needed anymore by the mixer. */ + if ( pEchoChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + pEchoChanEntry->usExtraSinTsiDependencyCnt--; + pEchoChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + } + else + { + /* Decrement the dependency count, but do not clear the mem index. */ + pEchoChanEntry->usExtraSinTsiDependencyCnt--; + } + + /* Indicate that the extra RIN TSI is not needed anymore by the mixer. */ + if ( pEchoChanEntry->usExtraRinTsiDependencyCnt == 1 ) + { + pEchoChanEntry->usExtraRinTsiDependencyCnt--; + pEchoChanEntry->usExtraRinTsiMemIndex = cOCT6100_INVALID_INDEX; + } + + /* Update the chip stats structure. */ + pSharedInfo->ChipStats.usNumEcChanUsingMixer--; + + pBridgeEntry->usNumClients--; + + /* For sure we have to mute the ports of this channel to be removed. */ + ulResult = Oct6100ApiMutePorts( + f_pApiInstance, + f_usChanIndex, + pEchoChanEntry->usRinTsstIndex, + pEchoChanEntry->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Travel through the channels that were heard by the participant removed and check if their Rin port must be muted. */ + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + { + if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, ausMutePortChannelIndexes[ ulMutePortChannelIndex ] ); + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + if ( pTempParticipant->fFlexibleMixerCreated == FALSE ) + { + /* Check if the Rin port must be muted on this channel. */ + ulResult = Oct6100ApiMutePorts( + f_pApiInstance, + ausMutePortChannelIndexes[ ulMutePortChannelIndex ], + pTempEchoChanEntry->usRinTsstIndex, + pTempEchoChanEntry->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else /* if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == cOCT6100_INVALID_INDEX ) */ + { + /* No more channels to check for muting. */ + break; + } + } + } + else /* if ( f_pConfBridgeRemove->fRemoveAll == TRUE ) */ + { + UINT16 usMainChannelIndex; + + for ( usMainChannelIndex = 0 ; usMainChannelIndex < pSharedInfo->ChipConfig.usMaxChannels ; usMainChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, usMainChannelIndex ); + + /* If this channel is on the bridge we are closing all the channels. */ + if ( ( pEchoChanEntry->fReserved == TRUE ) && ( pEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) ) + { + /* Remember to mute the port on this channel. */ + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + { + if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == usMainChannelIndex ) + { + break; + } + else if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == cOCT6100_INVALID_INDEX ) + { + ausMutePortChannelIndexes[ ulMutePortChannelIndex ] = usMainChannelIndex; + break; + } + } + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pParticipant, pEchoChanEntry->usFlexConfParticipantIndex ); + + /* Search through the list of API channel entry for the ones on to this bridge. */ + for ( usChannelIndex = (UINT16)( usMainChannelIndex + 1 ); usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + if ( pTempEchoChanEntry->fReserved == TRUE ) + { + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Everyone that we can hear must be removed. */ + if ( ( ( pParticipant->ulListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) == 0x0 ) + && ( pParticipant->fFlexibleMixerCreated == TRUE ) + && ( pTempEchoChanEntry->fMute == FALSE ) ) + { + /* First update the current channel's mixer. */ + ulResult = Oct6100ApiBridgeRemoveParticipantFromChannel( + f_pApiInstance, + f_usBridgeIndex, + usChannelIndex, + usMainChannelIndex, + TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Check if this participant can hear us. */ + if ( ( ( pTempParticipant->ulListenerMask & ( 0x1 << pParticipant->ulListenerMaskIndex ) ) == 0x0 ) + && ( pTempParticipant->fFlexibleMixerCreated == TRUE ) + && ( pEchoChanEntry->fMute == FALSE ) ) + { + /* Then update this channel's mixer. */ + ulResult = Oct6100ApiBridgeRemoveParticipantFromChannel( + f_pApiInstance, + f_usBridgeIndex, + usMainChannelIndex, + usChannelIndex, + TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + } + + /* Check if must manually clear the Sin copy event. */ + if ( ( pEchoChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) + && ( pEchoChanEntry->fCopyEventCreated == TRUE ) ) + { + /* Transform event into no-operation. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pEchoChanEntry->usSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now remove the copy event from the event list. */ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, pEchoChanEntry->usSinCopyEventIndex, cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + pEchoChanEntry->fCopyEventCreated = FALSE; + } + + /* Release an entry for the participant. */ + ulResult = Oct6100ApiReleaseFlexConfParticipantEntry( f_pApiInstance, pEchoChanEntry->usFlexConfParticipantIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + /*=======================================================================*/ + /* Update the event and channel API structure */ + + pEchoChanEntry->usBridgeIndex = cOCT6100_INVALID_INDEX; + + pEchoChanEntry->usLoadEventIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usSubStoreEventIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usSinCopyEventIndex = cOCT6100_INVALID_INDEX; + + /* Indicate that the Extra SIN TSI is not needed anymore by the mixer. */ + if ( pEchoChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + pEchoChanEntry->usExtraSinTsiDependencyCnt--; + pEchoChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + } + else + { + /* Decrement the dependency count, but do not clear the mem index. */ + pEchoChanEntry->usExtraSinTsiDependencyCnt--; + } + + /* Indicate that the Extra RIN TSI is not needed anymore by the mixer. */ + if ( pEchoChanEntry->usExtraRinTsiDependencyCnt == 1 ) + { + pEchoChanEntry->usExtraRinTsiDependencyCnt--; + pEchoChanEntry->usExtraRinTsiMemIndex = cOCT6100_INVALID_INDEX; + } + + /* Update the chip stats structure. */ + pSharedInfo->ChipStats.usNumEcChanUsingMixer--; + } + } + + /* Travel through the channels that were heard by the participant removed and check if their Rin port must be muted. */ + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + { + if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, ausMutePortChannelIndexes[ ulMutePortChannelIndex ] ); + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + if ( pTempParticipant->fFlexibleMixerCreated == FALSE ) + { + /* Check if the Rin port must be muted on this channel. */ + ulResult = Oct6100ApiMutePorts( + f_pApiInstance, + ausMutePortChannelIndexes[ ulMutePortChannelIndex ], + pTempEchoChanEntry->usRinTsstIndex, + pTempEchoChanEntry->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else /* if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == cOCT6100_INVALID_INDEX ) */ + { + /* No more channels to check for muting. */ + break; + } + + /* Clear the flexible conf bridge participant index. */ + pTempEchoChanEntry->usFlexConfParticipantIndex = cOCT6100_INVALID_INDEX; + } + + /* No more clients on bridge. */ + pBridgeEntry->usNumClients = 0; + } + } + else /* if ( f_fFlexibleConfBridge == FALSE ) */ + { + if ( f_pConfBridgeRemove->fRemoveAll == FALSE ) + { + /* The channel index is valid. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_usChanIndex ); + + if ( f_fTap == TRUE ) + { + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( pSharedInfo, pBridgeEntry, pEchoChanEntry->usTapBridgeIndex ); + } + + /* Get a pointer to the event entry. */ + if ( f_usCopyEventIndex != cOCT6100_INVALID_INDEX ) + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pCopyEventEntry, f_usCopyEventIndex ); + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pSubStoreEventEntry, f_usSubStoreEventIndex ); + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLoadEventEntry, f_usLoadEventIndex ); + + /*=======================================================================*/ + /* Check if have to modify the silence load event. */ + + if ( pBridgeEntry->usNumClients != 1 ) + { + if ( pBridgeEntry->usSilenceLoadEventPtr != cOCT6100_INVALID_INDEX ) + { + if ( pBridgeEntry->usSilenceLoadEventPtr == f_usLoadEventIndex ) + { + /* Make sure the next event becomes the silence event. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pLoadEventEntry->usNextEventPtr * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_LOAD; + WriteParams.usWriteData |= 1534; /* TSI index 1534 reserved for silence */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the software model to remember the silence load. */ + pBridgeEntry->usSilenceLoadEventPtr = pLoadEventEntry->usNextEventPtr; + } + else + { + /* Somebody else is the silence event, no need to worry. */ + } + } + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Clear the Load event. */ + + /* First verify if the event to be removed was a load event. */ + if ( f_usLoadEventIndex == pBridgeEntry->usLoadIndex ) + { + /* Change the next entry if one is present to a load event to keep the bridge alive. */ + if ( pBridgeEntry->usNumClients == 1 ) + { + /* There is no other entry on the bridge, no need to search for an Accumulate event. */ + pBridgeEntry->usLoadIndex = cOCT6100_INVALID_INDEX; + + /* Clear the silence event, for sure it's invalid. */ + pBridgeEntry->usSilenceLoadEventPtr = cOCT6100_INVALID_INDEX; + } + else + { + /* Search for an accumulate event to tranform into a Load event. */ + usTempEventIndex = pLoadEventEntry->usNextEventPtr; + ulLoopCount = 0; + + /* Find the copy entry before the entry to remove. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex ); + + while( pTempEntry->usEventType != cOCT6100_MIXER_CONTROL_MEM_SUB_STORE && + pTempEntry->usEventType != cOCT6100_MIXER_CONTROL_MEM_STORE ) + { + if ( pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE ) + { + /* Change this entry into a load event. */ + ReadParams.ulReadAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usTempEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + WriteParams.usWriteData = (UINT16)(( usReadData & 0x1FFF ) | cOCT6100_MIXER_CONTROL_MEM_LOAD); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set this entry as the load index. */ + pBridgeEntry->usLoadIndex = usTempEventIndex; + + /* Update the software model. */ + pTempEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_LOAD; + + /* Stop searching. */ + break; + } + + /* Go to the next entry into the list. */ + usTempEventIndex = pTempEntry->usNextEventPtr; + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex ); + + ulLoopCount++; + if ( ulLoopCount == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_FATAL_9B; + } + } + } + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usLoadEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Clear the substract and store event. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Clear the Copy event - if needed. */ + + if ( f_usCopyEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Transform event into no-operation. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( f_fTap == FALSE ) + { + /* Set remove Sin copy event flag to remove the event from the mixer's list. */ + fRemoveSinCopy = TRUE; + + /* Clear the copy event created flag. */ + pEchoChanEntry->fCopyEventCreated = FALSE; + } + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Now remove the event from the event list. */ + + /* Look for the entry that is pointing at the first entry of our bridge. */ + if ( f_fTap == FALSE ) + { + ulResult = Oct6100ApiGetPrevLastSubStoreEvent( f_pApiInstance, f_usBridgeIndex, pBridgeEntry->usFirstLoadEventPtr, &usPreviousEventIndex ); + } + else + { + ulResult = Oct6100ApiGetPrevLastSubStoreEvent( f_pApiInstance, pEchoChanEntry->usTapBridgeIndex, pBridgeEntry->usFirstLoadEventPtr, &usPreviousEventIndex ); + } + + if ( ulResult != cOCT6100_ERR_OK ) + { + /* If the entry was not found, we now check for the Sout copy event section/list. */ + if ( ulResult == cOCT6100_ERR_CONF_MIXER_EVENT_NOT_FOUND ) + { + if ( pSharedInfo->MixerInfo.usLastSoutCopyEventPtr == cOCT6100_INVALID_INDEX ) + { + /* No Sout copy, it has to be the head node. */ + usPreviousEventIndex = cOCT6100_MIXER_HEAD_NODE; + } + else + { + /* Use the last Sout copy event. */ + usPreviousEventIndex = pSharedInfo->MixerInfo.usLastSoutCopyEventPtr; + } + } + else + { + return cOCT6100_ERR_FATAL_27; + } + } + + if ( pBridgeEntry->usNumClients == 1 ) + { + /* An entry was found, now, modify it's value. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usPreviousEventIndex ); + + /* Now modify the previous last Sub Store event from another bridge. */ + pTempEntry->usNextEventPtr = pSubStoreEventEntry->usNextEventPtr; + + /*=======================================================================*/ + /* Modify the last node of the previous bridge to point to the next bridge. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usPreviousEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pTempEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Set the event pointer info in the bridge stucture. */ + pBridgeEntry->usFirstLoadEventPtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usFirstSubStoreEventPtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usLastSubStoreEventPtr = cOCT6100_INVALID_INDEX; + + /*=======================================================================*/ + /* Update the global mixer pointers. */ + if ( pSharedInfo->MixerInfo.usFirstBridgeEventPtr == f_usLoadEventIndex && + pSharedInfo->MixerInfo.usLastBridgeEventPtr == f_usSubStoreEventIndex ) + { + /* There is no more bridge entry in the mixer link list. */ + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastBridgeEventPtr = cOCT6100_INVALID_INDEX; + } + else if ( pSharedInfo->MixerInfo.usFirstBridgeEventPtr == f_usLoadEventIndex ) + { + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = pSubStoreEventEntry->usNextEventPtr; + } + else if ( pSharedInfo->MixerInfo.usLastBridgeEventPtr == f_usSubStoreEventIndex ) + { + pSharedInfo->MixerInfo.usLastBridgeEventPtr = usPreviousEventIndex; + } + /*=======================================================================*/ + + if ( f_fTap == TRUE ) + { + /* The channel being tapped is not tapped anymore. */ + /* There is no direct way of finding the tap, so loop through all channels and find the */ + /* tapped channel index. */ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + if ( pTempEchoChanEntry->usTapChanIndex == f_usChanIndex ) + { + tPOCT6100_API_CONF_BRIDGE pTempBridgeEntry; + + pTempEchoChanEntry->fBeingTapped = FALSE; + pTempEchoChanEntry->usTapChanIndex = cOCT6100_INVALID_INDEX; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( pSharedInfo, pTempBridgeEntry, f_usBridgeIndex ); + + pTempBridgeEntry->usNumTappedClients--; + + /* Re-assign Rin TSST for tapped channel. */ + if ( pTempEchoChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pTempEchoChanEntry->usRinTsstIndex, + pTempEchoChanEntry->usRinRoutTsiMemIndex, + pTempEchoChanEntry->TdmConfig.byRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + break; + } + } + + /* Check if our model is broken. */ + if ( usChannelIndex == pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_FATAL_D3; + } + } + else /* pBridgeEntry->usNumClients > 1 */ + { + if ( pBridgeEntry->usFirstLoadEventPtr != f_usLoadEventIndex ) + { + /* Now find the load entry of this bridge pointing at this load event */ + ulResult = Oct6100ApiGetPreviousEvent( f_pApiInstance, pBridgeEntry->usFirstLoadEventPtr, f_usLoadEventIndex, 0, &usPreviousEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Remove the load event to the list. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usPreviousEventIndex ); + + /* Now modify the previous last Sub Store event from another bridge. */ + pTempEntry->usNextEventPtr = pLoadEventEntry->usNextEventPtr; + + /*=======================================================================*/ + /* Modify the previous node. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usPreviousEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pTempEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Now find the last load entry of this bridge ( the one pointing at the first sub-store event ). */ + if ( pBridgeEntry->usFirstSubStoreEventPtr == f_usSubStoreEventIndex ) + { + /* Must start with the first load to get the entry before the first sub store. */ + ulResult = Oct6100ApiGetPreviousEvent( f_pApiInstance, pBridgeEntry->usFirstLoadEventPtr, f_usSubStoreEventIndex, 0, &usPreviousEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + /* Must start with the first load to get the entry before the first sub store. */ + ulResult = Oct6100ApiGetPreviousEvent( f_pApiInstance, pBridgeEntry->usFirstSubStoreEventPtr, f_usSubStoreEventIndex, 0, &usPreviousEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usPreviousEventIndex ); + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pSubStoreEventEntry, f_usSubStoreEventIndex ); + + /* Now modify the last load event of the bridge. */ + pTempEntry->usNextEventPtr = pSubStoreEventEntry->usNextEventPtr; + + /*=======================================================================*/ + /* Modify the last node of the other bridge. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usPreviousEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pTempEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Update the bridge pointers. */ + + if ( pBridgeEntry->usFirstLoadEventPtr == f_usLoadEventIndex ) + pBridgeEntry->usFirstLoadEventPtr = pLoadEventEntry->usNextEventPtr; + + if ( pBridgeEntry->usFirstSubStoreEventPtr == f_usSubStoreEventIndex ) + pBridgeEntry->usFirstSubStoreEventPtr = pSubStoreEventEntry->usNextEventPtr; + + if ( pBridgeEntry->usLastSubStoreEventPtr == f_usSubStoreEventIndex ) + pBridgeEntry->usLastSubStoreEventPtr = usPreviousEventIndex; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Update the global mixer pointers. */ + + if ( pSharedInfo->MixerInfo.usFirstBridgeEventPtr == f_usLoadEventIndex ) + { + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = pLoadEventEntry->usNextEventPtr; + } + + if ( pSharedInfo->MixerInfo.usLastBridgeEventPtr == f_usSubStoreEventIndex ) + { + pSharedInfo->MixerInfo.usLastBridgeEventPtr = usPreviousEventIndex; + } + /*=======================================================================*/ + + } + + /* Check if must remove the Sin copy event from the event list. */ + if ( fRemoveSinCopy == TRUE ) + { + /* Now remove the copy event from the event list. */ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, f_usCopyEventIndex, cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Get the channel. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_usChanIndex ); + + /* Reprogram the TSST entry correctly if the Extra SIN TSI entry was released. */ + if ( ( pEchoChanEntry->usExtraSinTsiDependencyCnt == 1 ) && ( f_fTap == FALSE ) ) + { + if ( pEchoChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pEchoChanEntry->usSinTsstIndex, + pEchoChanEntry->usSinSoutTsiMemIndex, + pEchoChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* If the silence TSI is loaded on this port, update with the original sin TSI. */ + if ( pEchoChanEntry->usSinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pEchoChanEntry->usSinSilenceEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pEchoChanEntry->usSinSoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /* Set the event entries as free. */ + pLoadEventEntry->fReserved = FALSE; + pLoadEventEntry->usEventType = cOCT6100_INVALID_INDEX; + pLoadEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + pSubStoreEventEntry->fReserved = FALSE; + pSubStoreEventEntry->usEventType = cOCT6100_INVALID_INDEX; + pSubStoreEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + if ( pCopyEventEntry != NULL ) + { + pCopyEventEntry->fReserved = FALSE; + pCopyEventEntry->usEventType = cOCT6100_INVALID_INDEX; + pCopyEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + } + + pBridgeEntry->usNumClients--; + + /*=======================================================================*/ + /* Update the event and channel API structure */ + pEchoChanEntry->usBridgeIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usLoadEventIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usSubStoreEventIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usSinCopyEventIndex = cOCT6100_INVALID_INDEX; + + /* Indicate that the Extra SIN TSI is not needed anymore by the mixer. */ + if ( pEchoChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + pEchoChanEntry->usExtraSinTsiDependencyCnt--; + pEchoChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + } + else + { + /* Decrement the dependency count, but do not clear the mem index. */ + pEchoChanEntry->usExtraSinTsiDependencyCnt--; + } + + /* Update the chip stats structure. */ + pSharedInfo->ChipStats.usNumEcChanUsingMixer--; + + if ( f_fTap == TRUE ) + { + /* Can now close the bridge. */ + tOCT6100_CONF_BRIDGE_CLOSE BridgeClose; + + Oct6100ConfBridgeCloseDef( &BridgeClose ); + + BridgeClose.ulConfBridgeHndl = cOCT6100_HNDL_TAG_CONF_BRIDGE | (pBridgeEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | pEchoChanEntry->usTapBridgeIndex; + + ulResult = Oct6100ConfBridgeCloseSer( f_pApiInstance, &BridgeClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + pEchoChanEntry->usTapBridgeIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->fTap = FALSE; + } + + /* Check if the Rin port must be muted. */ + ulResult = Oct6100ApiMutePorts( + f_pApiInstance, + f_usChanIndex, + pEchoChanEntry->usRinTsstIndex, + pEchoChanEntry->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + } + else /* f_ulBridgeChanRemove->fRemoveAll == TRUE ) */ + { + UINT16 usNextEventPtr; + + /* Save the next event pointer before invalidating everything. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pSubStoreEventEntry, pBridgeEntry->usLastSubStoreEventPtr ); + + usNextEventPtr = pSubStoreEventEntry->usNextEventPtr; + + /* Search through the list of API channel entry for the ones on to the specified bridge. */ + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxChannels; i++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, i ); + + if ( pEchoChanEntry->fReserved == TRUE ) + { + if ( ( pEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) && ( pEchoChanEntry->fTap == FALSE ) ) + { + /* Check if we are being tapped. If so, remove the channel that taps us from the conference. */ + /* The removal of the channel will make sure the Rin TSST is re-assigned. */ + if ( pEchoChanEntry->fBeingTapped == TRUE ) + { + tOCT6100_CONF_BRIDGE_CHAN_REMOVE ChanRemove; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, pEchoChanEntry->usTapChanIndex ); + + ulResult = Oct6100ConfBridgeChanRemoveDef( &ChanRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ChanRemove.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | (pTempEchoChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | pEchoChanEntry->usTapChanIndex; + + ulResult = Oct6100ConfBridgeChanRemoveSer( f_pApiInstance, &ChanRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*=======================================================================*/ + /* Clear the Load event. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pEchoChanEntry->usLoadEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Clear the Substract and store event. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pEchoChanEntry->usSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*=======================================================================*/ + + /*=======================================================================*/ + /* Clear the SIN copy event.*/ + + if ( pEchoChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Transform event into no-operation. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pEchoChanEntry->usSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Get a pointer to the event entry. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pCopyEventEntry, pEchoChanEntry->usSinCopyEventIndex ); + + /* Update the next event pointer if required. */ + if ( usNextEventPtr == pEchoChanEntry->usSinCopyEventIndex ) + usNextEventPtr = pCopyEventEntry->usNextEventPtr; + + /* Now remove the copy event from the event list. */ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, pEchoChanEntry->usSinCopyEventIndex, cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear the copy event created flag. */ + pEchoChanEntry->fCopyEventCreated = FALSE; + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Update the event and channel API structure */ + + /* Reprogram the TSST entry correctly if the Extra SIN TSI entry was released.*/ + if ( pEchoChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + if ( pEchoChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pEchoChanEntry->usSinTsstIndex, + pEchoChanEntry->usSinSoutTsiMemIndex, + pEchoChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* If the silence TSI is loaded on this port, update with the original Sin TSI. */ + if ( pEchoChanEntry->usSinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pEchoChanEntry->usSinSilenceEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pEchoChanEntry->usSinSoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLoadEventEntry, pEchoChanEntry->usLoadEventIndex ); + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pSubStoreEventEntry, pEchoChanEntry->usSubStoreEventIndex ); + + /* Set the event entries as free. */ + pLoadEventEntry->fReserved = FALSE; + pLoadEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pLoadEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + pSubStoreEventEntry->fReserved = FALSE; + pSubStoreEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pSubStoreEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + if ( pCopyEventEntry != NULL ) + { + pCopyEventEntry->fReserved = FALSE; + pCopyEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pCopyEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + } + + /* Indicate that the Extra SIN TSI is not needed anymore by the mixer. */ + if ( pEchoChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + pEchoChanEntry->usExtraSinTsiDependencyCnt--; + pEchoChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + } + else + { + /* Decrement the dependency count, but do not clear the mem index. */ + pEchoChanEntry->usExtraSinTsiDependencyCnt--; + } + + /* Invalidate the channel entry. */ + pEchoChanEntry->usLoadEventIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usSubStoreEventIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usSinCopyEventIndex = cOCT6100_INVALID_INDEX; + + /* Update the chip stats structure. */ + pSharedInfo->ChipStats.usNumEcChanUsingMixer--; + + /*=======================================================================*/ + } + } + } + + ulResult = Oct6100ApiGetPrevLastSubStoreEvent( f_pApiInstance, f_usBridgeIndex, pBridgeEntry->usFirstLoadEventPtr, &usPreviousEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( cOCT6100_ERR_CONF_MIXER_EVENT_NOT_FOUND == ulResult ) + { + if ( pSharedInfo->MixerInfo.usLastSoutCopyEventPtr == cOCT6100_INVALID_INDEX ) + { + usPreviousEventIndex = cOCT6100_MIXER_HEAD_NODE; + } + else + { + usPreviousEventIndex = pSharedInfo->MixerInfo.usLastSoutCopyEventPtr; + } + } + else + { + return cOCT6100_ERR_FATAL_28; + } + } + + /* An Entry was found, now, modify it's value. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usPreviousEventIndex ); + + /* Now modify the previous last Sub Store event from another bridge.*/ + /* It will now point at the next bridge, or copy events. */ + pTempEntry->usNextEventPtr = usNextEventPtr; + + /*=======================================================================*/ + /* Modify the last node of the other bridge. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usPreviousEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = pTempEntry->usNextEventPtr; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*=======================================================================*/ + + /*=======================================================================*/ + /* Update the global mixer pointers. */ + if ( pSharedInfo->MixerInfo.usFirstBridgeEventPtr == pBridgeEntry->usFirstLoadEventPtr && + pSharedInfo->MixerInfo.usLastBridgeEventPtr == pBridgeEntry->usLastSubStoreEventPtr ) + { + /* This bridge was the only one with event in the list. */ + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastBridgeEventPtr = cOCT6100_INVALID_INDEX; + } + else if ( pSharedInfo->MixerInfo.usFirstBridgeEventPtr == pBridgeEntry->usFirstLoadEventPtr ) + { + /* This bridge was the first bridge. */ + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = usNextEventPtr; + } + else if ( pSharedInfo->MixerInfo.usLastBridgeEventPtr == pBridgeEntry->usLastSubStoreEventPtr ) + { + /* This bridge was the last bridge.*/ + pSharedInfo->MixerInfo.usLastBridgeEventPtr = usPreviousEventIndex; + } + /*=======================================================================*/ + + /* Set the event pointer info in the bridge stucture. */ + pBridgeEntry->usFirstLoadEventPtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usFirstSubStoreEventPtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usLastSubStoreEventPtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usLoadIndex = cOCT6100_INVALID_INDEX; + + pBridgeEntry->usSilenceLoadEventPtr = cOCT6100_INVALID_INDEX; + + /* Set the number of clients to 0. */ + pBridgeEntry->usNumClients = 0; + + /* Search through the list of API channel entry for the ones on to the specified bridge. */ + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxChannels; i++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, i ); + + if ( pEchoChanEntry->fReserved == TRUE ) + { + if ( ( pEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) && ( pEchoChanEntry->fTap == FALSE ) ) + { + pEchoChanEntry->usBridgeIndex = cOCT6100_INVALID_INDEX; + + /* Check if the Rin port must be muted. */ + ulResult = Oct6100ApiMutePorts( + f_pApiInstance, + (UINT16)( i & 0xFFFF ), + pEchoChanEntry->usRinTsstIndex, + pEchoChanEntry->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBridgeRemoveParticipantFromChannel + +Description: This will remove a flexible conference participant from + a channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_usBridgeIndex Bridge index where this channel is located. +f_usSourceChannelIndex Source channel to copy voice from. +f_usDestinationChannelIndex Destination channel to store resulting voice to. +f_fRemovePermanently Whether to remove permanently this participant. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBridgeRemoveParticipantFromChannel +UINT32 Oct6100ApiBridgeRemoveParticipantFromChannel( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usSourceChannelIndex, + IN UINT16 f_usDestinationChannelIndex, + IN UINT8 f_fRemovePermanently ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + + tPOCT6100_API_MIXER_EVENT pLoadEventEntry; + tPOCT6100_API_MIXER_EVENT pStoreEventEntry; + tPOCT6100_API_MIXER_EVENT pCopyEventEntry; + tPOCT6100_API_MIXER_EVENT pTempEntry; + tPOCT6100_API_MIXER_EVENT pLoadTempEntry; + tPOCT6100_API_MIXER_EVENT pLastEventEntry; + + tPOCT6100_API_CHANNEL pDestinationChanEntry; + + tPOCT6100_API_FLEX_CONF_PARTICIPANT pDestinationParticipant; + + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + + UINT32 ulResult; + UINT32 ulLoopCount; + UINT16 usLoadOrAccumulateEventIndex; + UINT16 usTempEventIndex; + UINT16 usPreviousEventIndex; + UINT16 usLastEventIndex; + + UINT16 usReadData; + BOOL fLastEvent = FALSE; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, f_usBridgeIndex ); + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pDestinationChanEntry, f_usDestinationChannelIndex ); + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pDestinationParticipant, pDestinationChanEntry->usFlexConfParticipantIndex ); + + /* Check if the mixer has been created on this channel. */ + if ( pDestinationParticipant->fFlexibleMixerCreated == TRUE ) + { + /*=======================================================================*/ + /* Clear the Load or Accumulate event.*/ + + usTempEventIndex = pDestinationChanEntry->usLoadEventIndex; + ulLoopCount = 0; + + /* Find the Load or Accumulate event entry. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLoadEventEntry, usTempEventIndex ); + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pStoreEventEntry, pDestinationChanEntry->usSubStoreEventIndex ); + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex ); + + pLastEventEntry = pLoadEventEntry; + usLastEventIndex = usTempEventIndex; + + while( pTempEntry->usEventType != cOCT6100_MIXER_CONTROL_MEM_SUB_STORE && + pTempEntry->usEventType != cOCT6100_MIXER_CONTROL_MEM_STORE ) + { + /* If this is the entry we are looking for. */ + if ( pTempEntry->usSourceChanIndex == f_usSourceChannelIndex ) + { + /* Check if this is a Load or Accumulate event. */ + if ( pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_LOAD ) + { + /* This is the first entry. Check if next entry is an accumulate. */ + pLoadTempEntry = pTempEntry; + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, pTempEntry->usNextEventPtr ); + + if ( pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE ) + { + /* Change this entry into a Load event. */ + ReadParams.ulReadAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pLoadTempEntry->usNextEventPtr * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + WriteParams.usWriteData = (UINT16)(( usReadData & 0x1FFF ) | cOCT6100_MIXER_CONTROL_MEM_LOAD); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the channel information with this new load event. */ + pDestinationChanEntry->usLoadEventIndex = pLoadTempEntry->usNextEventPtr; + + /* Update the software model. */ + pTempEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_LOAD; + + /* Get the previous event. */ + ulResult = Oct6100ApiGetPreviousEvent( f_pApiInstance, cOCT6100_MIXER_HEAD_NODE, usTempEventIndex, 0, &usPreviousEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLastEventEntry, usPreviousEventIndex ); + usLastEventIndex = usPreviousEventIndex; + + /* Stop searching. */ + break; + } + else if ( pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_STORE ) + { + /* Get back the event to remove. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex ); + + /* This is the only event on this channel so we can clear everything up. */ + fLastEvent = TRUE; + + /* Get the previous event. */ + ulResult = Oct6100ApiGetPreviousEvent( f_pApiInstance, cOCT6100_MIXER_HEAD_NODE, usTempEventIndex, 0, &usPreviousEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLastEventEntry, usPreviousEventIndex ); + usLastEventIndex = usPreviousEventIndex; + + /* Stop searching. */ + break; + } + else + { + /* Software model is broken. */ + return cOCT6100_ERR_FATAL_C5; + } + + } + else if ( pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE ) + { + /* Simply remove the entry. */ + + /* Get the previous event. */ + ulResult = Oct6100ApiGetPreviousEvent( f_pApiInstance, cOCT6100_MIXER_HEAD_NODE, usTempEventIndex, 0, &usPreviousEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLastEventEntry, usPreviousEventIndex ); + usLastEventIndex = usPreviousEventIndex; + + /* Stop searching. */ + break; + } + else + { + /* Software model is broken. */ + return cOCT6100_ERR_FATAL_C6; + } + } + + /* Go to the next entry into the list. */ + usTempEventIndex = pTempEntry->usNextEventPtr; + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex ); + + ulLoopCount++; + if ( ulLoopCount == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_FATAL_C8; + } + + /* Check if we found what we were looking for. */ + if ( pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_STORE + || pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_SUB_STORE ) + { + /* Software model is broken. */ + return cOCT6100_ERR_FATAL_C7; + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Clear the Store event - if needed. */ + + if ( fLastEvent == TRUE ) + { + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pDestinationChanEntry->usSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Clear the Load or Accumulate event. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usTempEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save this event index. It's the Load or Accumulate we want to remove from the list later. */ + usLoadOrAccumulateEventIndex = usTempEventIndex; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Clear the Copy event - if needed. */ + + if ( ( fLastEvent == TRUE ) && ( pDestinationChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) && ( f_fRemovePermanently == TRUE ) ) + { + /* Transform event into no-operation. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pDestinationChanEntry->usSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* The event remove from the list will be done below. */ + + /* Clear the copy event created flag. */ + pDestinationChanEntry->fCopyEventCreated = FALSE; + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /*=======================================================================*/ + /* Remove the events from the mixer event list.*/ + /*=======================================================================*/ + /*=======================================================================*/ + + /*=======================================================================*/ + /* Remove the Load or Accumulate event from the event list. */ + + if ( fLastEvent == FALSE ) + { + /*=======================================================================*/ + /* Remove the Accumulate event from the event list. */ + + /* We saved the Load or Accumulate event above. We also saved the previous event. Use those. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLoadEventEntry, usLoadOrAccumulateEventIndex ); + + /* Now modify the previous last event. */ + pLastEventEntry->usNextEventPtr = pLoadEventEntry->usNextEventPtr; + + /* Modify the previous node. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usLastEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = pLastEventEntry->usNextEventPtr; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if this is the first load event on the bridge. */ + if ( pBridgeEntry->usFirstLoadEventPtr == usLoadOrAccumulateEventIndex ) + { + pBridgeEntry->usFirstLoadEventPtr = pLoadEventEntry->usNextEventPtr; + } + + /* Check if this was the first load of all bridges. */ + if ( pSharedInfo->MixerInfo.usFirstBridgeEventPtr == usLoadOrAccumulateEventIndex ) + { + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = pLoadEventEntry->usNextEventPtr; + } + + /*=======================================================================*/ + } + else /* if ( fLastEvent == TRUE ) */ + { + /*=======================================================================*/ + /* Remove the Load event from the event list. */ + + /* Look for the entry that is pointing at the first entry of our mixer. */ + ulResult = Oct6100ApiGetPreviousEvent( f_pApiInstance, cOCT6100_MIXER_HEAD_NODE, usLoadOrAccumulateEventIndex, 0, &usPreviousEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* An Entry was found, now, modify it's value. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usPreviousEventIndex ); + + /* Check if this is a Sout copy event. */ + if ( pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_COPY ) + { + /* No more previous bridges. */ + } + + /* Now modify the previous last Store or Sub-Store or Head-Node event from another bridge/channel. */ + pTempEntry->usNextEventPtr = pStoreEventEntry->usNextEventPtr; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Modify the last node of the previous bridge/channel to point to the next bridge. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usPreviousEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = pTempEntry->usNextEventPtr; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Set the event pointer info in the bridge stucture. */ + + if ( pBridgeEntry->usFirstLoadEventPtr == pDestinationChanEntry->usLoadEventIndex ) + { + UINT16 usChannelIndex; + tPOCT6100_API_CHANNEL pTempEchoChanEntry; + + pBridgeEntry->usFirstSubStoreEventPtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usFirstLoadEventPtr = cOCT6100_INVALID_INDEX; + + /* Find the next channel in this conference that could give us valid values. */ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + if ( ( usChannelIndex != f_usDestinationChannelIndex ) && ( pTempEchoChanEntry->fReserved == TRUE ) ) + { + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + tPOCT6100_API_FLEX_CONF_PARTICIPANT pTempParticipant; + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + if ( pTempParticipant->fFlexibleMixerCreated == TRUE ) + { + pBridgeEntry->usFirstSubStoreEventPtr = pTempEchoChanEntry->usSubStoreEventIndex; + pBridgeEntry->usFirstLoadEventPtr = pTempEchoChanEntry->usLoadEventIndex; + break; + } + } + } + } + } + + /* Reprogram the TSST entry correctly if the extra SIN TSI entry was released. */ + if ( ( pDestinationChanEntry->usExtraSinTsiDependencyCnt == 1 ) && ( f_fRemovePermanently == TRUE ) ) + { + if ( pDestinationChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pDestinationChanEntry->usSinTsstIndex, + pDestinationChanEntry->usSinSoutTsiMemIndex, + pDestinationChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* If the silence TSI is loaded on this port, update with the original sin TSI. */ + if ( pDestinationChanEntry->usSinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pDestinationChanEntry->usSinSilenceEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pDestinationChanEntry->usSinSoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Reprogram the TSST entry correctly if the extra RIN TSI entry was released. */ + if ( ( pDestinationChanEntry->usExtraRinTsiDependencyCnt == 1 ) && ( f_fRemovePermanently == TRUE ) ) + { + if ( pDestinationChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pDestinationChanEntry->usRinTsstIndex, + pDestinationChanEntry->usRinRoutTsiMemIndex, + pDestinationChanEntry->TdmConfig.byRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /*=======================================================================*/ + /* Update the global mixer pointers. */ + + if ( pSharedInfo->MixerInfo.usFirstBridgeEventPtr == usLoadOrAccumulateEventIndex && + pSharedInfo->MixerInfo.usLastBridgeEventPtr == pDestinationChanEntry->usSubStoreEventIndex ) + { + /* There is no more bridge entry in the mixer link list. */ + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastBridgeEventPtr = cOCT6100_INVALID_INDEX; + } + else if ( pSharedInfo->MixerInfo.usFirstBridgeEventPtr == usLoadOrAccumulateEventIndex ) + { + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = pStoreEventEntry->usNextEventPtr; + } + else if ( pSharedInfo->MixerInfo.usLastBridgeEventPtr == pDestinationChanEntry->usSubStoreEventIndex ) + { + pSharedInfo->MixerInfo.usLastBridgeEventPtr = usPreviousEventIndex; + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Check if must remove the Sin copy event from the list. */ + + if ( ( pDestinationChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) && ( f_fRemovePermanently == TRUE ) ) + { + /* Now remove the copy event from the event list. */ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, pDestinationChanEntry->usSinCopyEventIndex, cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*=======================================================================*/ + + + + /*=======================================================================*/ + + if ( f_fRemovePermanently == TRUE ) + { + /* Set the event entries as free. */ + pLoadEventEntry->fReserved = FALSE; + pLoadEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pLoadEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + pStoreEventEntry->fReserved = FALSE; + pStoreEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pStoreEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + if ( pDestinationChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pCopyEventEntry, pDestinationChanEntry->usSinCopyEventIndex ); + + pCopyEventEntry->fReserved = FALSE; + pCopyEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pCopyEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + } + } + + /* Flexible mixer for this channel not created anymore. */ + pDestinationParticipant->fFlexibleMixerCreated = FALSE; + + /*=======================================================================*/ + } + + /*=======================================================================*/ + } + else /* if ( pDestinationChanEntry->fFlexibleMixerCreated == FALSE ) */ + { + /* This point should never be reached. */ + return cOCT6100_ERR_FATAL_C9; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeChanMuteSer + +Description: Mute an echo channel present on a conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeMute Pointer to conference bridge mute structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeChanMuteSer +UINT32 Oct6100ConfBridgeChanMuteSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CHAN_MUTE f_pConfBridgeMute ) +{ + UINT16 usChanIndex; + UINT16 usLoadEventIndex; + UINT16 usSubStoreEventIndex; + UINT32 ulResult; + UINT8 fFlexibleConferencing; + + /* Check the validity of the channel and conference bridge given. */ + ulResult = Oct6100ApiCheckBridgeMuteParams( + f_pApiInstance, + f_pConfBridgeMute, + &usChanIndex, + &usLoadEventIndex, + &usSubStoreEventIndex, + &fFlexibleConferencing ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Modify all resources needed by the conference bridge. */ + ulResult = Oct6100ApiUpdateBridgeMuteResources( + f_pApiInstance, + usChanIndex, + usLoadEventIndex, + usSubStoreEventIndex, + fFlexibleConferencing ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckBridgeMuteParams + +Description: Check the validity of the channel and conference bridge given. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeMute Pointer to conference bridge channel mute structure. +f_pusChannelIndex Pointer to a channel index. +f_pusLoadEventIndex Pointer to a load mixer event index. +f_pusSubStoreEventIndex Pointer to a sub-store mixer event index. +f_pfFlexibleConfBridge If this is a flexible conference bridge. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckBridgeMuteParams +UINT32 Oct6100ApiCheckBridgeMuteParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CHAN_MUTE f_pConfBridgeMute, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT16 f_pusLoadEventIndex, + OUT PUINT16 f_pusSubStoreEventIndex, + OUT PUINT8 f_pfFlexibleConfBridge ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + tPOCT6100_API_CHANNEL pEchoChanEntry; + UINT32 ulEntryOpenCnt; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges == 0 ) + return cOCT6100_ERR_CONF_BRIDGE_DISABLED; + + if ( f_pConfBridgeMute->ulChannelHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_HANDLE; + + /*=====================================================================*/ + /* Check the channel handle.*/ + + if ( (f_pConfBridgeMute->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + *f_pusChannelIndex = (UINT16)( f_pConfBridgeMute->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChanEntry, *f_pusChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeMute->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + /* Check if the channel is bound to a conference bridge. */ + if ( pEchoChanEntry->usBridgeIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_INVALID_HANDLE; + + /* Check if channel is already muted. */ + if ( pEchoChanEntry->fMute == TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_ALREADY_MUTED; + + /* Check if this is a tap channel, which is always mute. */ + if ( pEchoChanEntry->fTap == TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_ALWAYS_MUTE; + + /*=====================================================================*/ + + /*=====================================================================*/ + /* Check the conference bridge handle. */ + + if ( pEchoChanEntry->usBridgeIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, pEchoChanEntry->usBridgeIndex ) + + /* Check for errors. */ + if ( pBridgeEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + + if ( pBridgeEntry->fFlexibleConferencing == FALSE ) + { + /* Check the event entries.*/ + if ( pEchoChanEntry->usLoadEventIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_INVALID_HANDLE; + + if ( pEchoChanEntry->usSubStoreEventIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_INVALID_HANDLE; + } + + /*=====================================================================*/ + + /* Return the config of the channel and all other important information. */ + *f_pusSubStoreEventIndex = pEchoChanEntry->usSubStoreEventIndex; + *f_pusLoadEventIndex = pEchoChanEntry->usLoadEventIndex; + *f_pfFlexibleConfBridge = pBridgeEntry->fFlexibleConferencing; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateBridgeMuteResources + +Description: Modify the conference bridge entry for this channel in order + to mute the specified channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usChanIndex Index of the channel to be muted. +f_usLoadEventIndex Allocated entry for the Load event of the channel. +f_usSubStoreEventIndex Allocated entry for the substract and store event of the channel. +f_fFlexibleConfBridge If this is a flexible conference bridge. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateBridgeMuteResources +UINT32 Oct6100ApiUpdateBridgeMuteResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChanIndex, + IN UINT16 f_usLoadEventIndex, + IN UINT16 f_usSubStoreEventIndex, + IN UINT8 f_fFlexibleConfBridge ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + + tPOCT6100_API_CHANNEL pEchoChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + + tPOCT6100_API_MIXER_EVENT pLoadEventEntry; + tPOCT6100_API_MIXER_EVENT pSubStoreEventEntry; + tPOCT6100_API_MIXER_EVENT pTempEntry; + UINT32 ulResult; + UINT16 usTempEventIndex; + UINT32 ulLoopCount; + UINT16 usReadData; + + BOOL fCreateSilenceLoad = FALSE; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_usChanIndex ); + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, pEchoChanEntry->usBridgeIndex ) + + if ( f_fFlexibleConfBridge == TRUE ) + { + tPOCT6100_API_CHANNEL pTempEchoChanEntry; + UINT16 usChannelIndex; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pParticipant; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pTempParticipant; + + UINT16 ausMutePortChannelIndexes[ cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE ]; + UINT32 ulMutePortChannelIndex; + + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + ausMutePortChannelIndexes[ ulMutePortChannelIndex ] = cOCT6100_INVALID_INDEX; + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pParticipant, pEchoChanEntry->usFlexConfParticipantIndex ); + + /* Search through the list of API channel entry for the ones on to this bridge. */ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + if ( ( usChannelIndex != f_usChanIndex ) && ( pTempEchoChanEntry->fReserved == TRUE ) ) + { + if ( pTempEchoChanEntry->usBridgeIndex == pEchoChanEntry->usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if this participant can hear us. */ + if ( ( ( pTempParticipant->ulListenerMask & ( 0x1 << pParticipant->ulListenerMaskIndex ) ) == 0x0 ) + && ( pTempParticipant->fFlexibleMixerCreated == TRUE ) ) + { + /* Then update this channel's mixer. */ + ulResult = Oct6100ApiBridgeRemoveParticipantFromChannel( + f_pApiInstance, + pEchoChanEntry->usBridgeIndex, + f_usChanIndex, + usChannelIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( pTempParticipant->fFlexibleMixerCreated == FALSE ) + { + /* Remember to mute the port on this channel. */ + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + { + if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == usChannelIndex ) + { + break; + } + else if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == cOCT6100_INVALID_INDEX ) + { + ausMutePortChannelIndexes[ ulMutePortChannelIndex ] = usChannelIndex; + break; + } + } + } + } + } + } + } + + /* Travel through the channels that were heard by the participant removed and check if their Rin port must be muted. */ + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + { + if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, ausMutePortChannelIndexes[ ulMutePortChannelIndex ] ); + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + if ( pTempParticipant->fFlexibleMixerCreated == FALSE ) + { + /* Check if the Rin port must be muted on this channel. */ + ulResult = Oct6100ApiMutePorts( + f_pApiInstance, + ausMutePortChannelIndexes[ ulMutePortChannelIndex ], + pTempEchoChanEntry->usRinTsstIndex, + pTempEchoChanEntry->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_MIXER_ALL_MIXER_EVENT_ENTRY_OPENED ) + { + UINT32 ulTempResult; + + /* Cleanup resources, unmute channel... */ + ulTempResult = Oct6100ApiUpdateBridgeUnMuteResources( + f_pApiInstance, + f_usChanIndex, + f_usLoadEventIndex, + f_usSubStoreEventIndex, + TRUE ); + if ( ulTempResult != cOCT6100_ERR_OK ) + return ulTempResult; + else + return ulResult; + } + else + { + return ulResult; + } + } + } + } + else /* if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == cOCT6100_INVALID_INDEX ) */ + { + /* No more channels to check for muting. */ + break; + } + } + } + else /* if ( f_fFlexibleConfBridge == FALSE ) */ + { + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLoadEventEntry, f_usLoadEventIndex ); + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pSubStoreEventEntry, f_usSubStoreEventIndex ); + + /*=======================================================================*/ + /* Program the Load event. */ + + /* Create silence load if this is the first event of the bridge. */ + if ( f_usLoadEventIndex == pBridgeEntry->usFirstLoadEventPtr ) + fCreateSilenceLoad = TRUE; + + /* First check if this event was a load or an accumulate event, if it's a load */ + /* we need to find a new load. */ + if ( f_usLoadEventIndex == pBridgeEntry->usLoadIndex ) + { + /* Change the next entry if one is present to a load event to keep the bridge alive. */ + if ( pBridgeEntry->usNumClients == 1 ) + { + /* There is no other entry on the bridge, no need to search for an Accumulate event. */ + pBridgeEntry->usLoadIndex = cOCT6100_INVALID_INDEX; + } + else + { + /* Search for an accumulate event to tranform into a Load event. */ + usTempEventIndex = pLoadEventEntry->usNextEventPtr; + ulLoopCount = 0; + + /* Find the copy entry before the entry to remove. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex ); + + while( pTempEntry->usEventType != cOCT6100_MIXER_CONTROL_MEM_SUB_STORE && + pTempEntry->usEventType != cOCT6100_MIXER_CONTROL_MEM_STORE ) + { + if ( pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE ) + { + /* Change this entry into a load event. */ + ReadParams.ulReadAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usTempEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + WriteParams.usWriteData = (UINT16)(( usReadData & 0x1FFF ) | cOCT6100_MIXER_CONTROL_MEM_LOAD); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set this entry as the load index. */ + pBridgeEntry->usLoadIndex = usTempEventIndex; + + /* Update the software model. */ + pTempEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_LOAD; + + /* Stop searching. */ + break; + } + + /* Go to the next entry into the list. */ + usTempEventIndex = pTempEntry->usNextEventPtr; + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex ); + + ulLoopCount++; + if ( ulLoopCount == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_FATAL_9B; + } + } + } + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usLoadEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + /* Do not load the sample if the channel is muted. */ + if ( fCreateSilenceLoad == TRUE ) + { + if ( pBridgeEntry->usSilenceLoadEventPtr == cOCT6100_INVALID_INDEX ) + { + /* Instead of No-oping, load the silence TSI, to make sure the other conferences before us are not heard. */ + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_LOAD; + WriteParams.usWriteData |= 1534; /* TSI index 1534 reserved for silence */ + + /* Remember the silence load event. */ + pBridgeEntry->usSilenceLoadEventPtr = f_usLoadEventIndex; + } + else + { + /* Do nothing. */ + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + } + } + else + { + /* Do nothing. */ + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the software model. */ + pLoadEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Program the Substract and store event. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + /* Do not load the sample if the channel is muted. */ + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_STORE; + + /* If we have an extra Sin copy event, we know we are using the Sout port as a source. */ + if ( pEchoChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Sout input. */ + WriteParams.usWriteData |= pEchoChanEntry->TdmConfig.bySoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + } + else /* if ( pEchoChanEntry->usSinCopyEventIndex == cOCT6100_INVALID_INDEX ) */ + { + /* Rin input. */ + WriteParams.usWriteData |= pEchoChanEntry->TdmConfig.byRinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the software model. */ + pSubStoreEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_STORE; + + /*=======================================================================*/ + } + + /* Update the channel entry API structure */ + pEchoChanEntry->fMute = TRUE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeChanUnMuteSer + +Description: UnMute an echo channel present on a conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeUnMute Pointer to conference bridge channel unmute structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeChanUnMuteSer +UINT32 Oct6100ConfBridgeChanUnMuteSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE f_pConfBridgeUnMute ) +{ + UINT16 usChanIndex; + UINT16 usLoadEventIndex; + UINT16 usSubStoreEventIndex; + UINT8 fFlexibleConfBridge; + UINT32 ulResult; + + /* Check the validity of the channel and conference bridge given. */ + ulResult = Oct6100ApiCheckBridgeUnMuteParams( + f_pApiInstance, + f_pConfBridgeUnMute, + &usChanIndex, + &usLoadEventIndex, + &usSubStoreEventIndex, + &fFlexibleConfBridge ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Modify all resources needed by the conference bridge. */ + ulResult = Oct6100ApiUpdateBridgeUnMuteResources( + f_pApiInstance, + usChanIndex, + usLoadEventIndex, + usSubStoreEventIndex, + fFlexibleConfBridge ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckBridgeUnMuteParams + +Description: Check the validity of the channel and conference bridge given. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeUnMute Pointer to conference bridge channel unmute structure. +f_pusChannelIndex Pointer to the channel index fo the channel to be unmuted. +f_pusLoadEventIndex Pointer to the load index of the channel. +f_pusSubStoreEventIndex Pointer to the sub-store event of the channel. +f_pfFlexibleConfBridge If this is a flexible conference bridge. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckBridgeUnMuteParams +UINT32 Oct6100ApiCheckBridgeUnMuteParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE f_pConfBridgeUnMute, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT16 f_pusLoadEventIndex, + OUT PUINT16 f_pusSubStoreEventIndex, + OUT PUINT8 f_pfFlexibleConfBridge ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + tPOCT6100_API_CHANNEL pEchoChanEntry; + UINT32 ulEntryOpenCnt; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges == 0 ) + return cOCT6100_ERR_CONF_BRIDGE_DISABLED; + + if ( f_pConfBridgeUnMute->ulChannelHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_HANDLE; + + /*=====================================================================*/ + /* Check the channel handle.*/ + + if ( (f_pConfBridgeUnMute->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + *f_pusChannelIndex = (UINT16)( f_pConfBridgeUnMute->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChanEntry, *f_pusChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeUnMute->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + /* Check if the channel is bound to a conference bridge.*/ + if ( pEchoChanEntry->usBridgeIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_INVALID_HANDLE; + + /* Check if channel is already muted.*/ + if ( pEchoChanEntry->fMute == FALSE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_NOT_MUTED; + + /*=====================================================================*/ + + /*=====================================================================*/ + /* Check the conference bridge handle. */ + + if ( pEchoChanEntry->usBridgeIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, pEchoChanEntry->usBridgeIndex ) + + /* Check for errors. */ + if ( pBridgeEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + + /* Check the event entries.*/ + if ( pBridgeEntry->fFlexibleConferencing == FALSE ) + { + if ( pEchoChanEntry->usLoadEventIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_INVALID_HANDLE; + + /* Check the event entries.*/ + if ( pEchoChanEntry->usSubStoreEventIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_INVALID_HANDLE; + } + + /*=====================================================================*/ + + /* Return the config of the channel and all other important information.*/ + *f_pusSubStoreEventIndex = pEchoChanEntry->usSubStoreEventIndex; + *f_pusLoadEventIndex = pEchoChanEntry->usLoadEventIndex; + *f_pfFlexibleConfBridge = pBridgeEntry->fFlexibleConferencing; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateBridgeUnMuteResources + +Description: Modify the conference bridge entry for this channel in order + to un-mute the specified channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usChanIndex Index of the channel to be unmuted. +f_usLoadEventIndex Allocated entry for the Load event of the channel. +f_usSubStoreEventIndex Allocated entry for the substract and store event of the channel. +f_fFlexibleConfBridge If this is a flexible conference bridge. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateBridgeUnMuteResources +UINT32 Oct6100ApiUpdateBridgeUnMuteResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChanIndex, + IN UINT16 f_usLoadEventIndex, + IN UINT16 f_usSubStoreEventIndex, + IN UINT8 f_fFlexibleConfBridge ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + + tPOCT6100_API_CHANNEL pEchoChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + + tPOCT6100_API_MIXER_EVENT pLoadEventEntry; + tPOCT6100_API_MIXER_EVENT pSubStoreEventEntry; + tPOCT6100_API_MIXER_EVENT pTempEntry; + UINT32 ulResult; + UINT16 usTempEventIndex; + UINT32 ulLoopCount; + UINT16 usReadData; + + UINT16 usLoadEventType = cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE; + UINT16 usPreviousLoadIndex = cOCT6100_INVALID_INDEX; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_usChanIndex ); + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, pEchoChanEntry->usBridgeIndex ) + + if ( f_fFlexibleConfBridge == TRUE ) + { + tPOCT6100_API_CHANNEL pTempEchoChanEntry; + UINT16 usChannelIndex; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pParticipant; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pTempParticipant; + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pParticipant, pEchoChanEntry->usFlexConfParticipantIndex ); + + /* Before doing anything, check if the copy events must be created. */ + if ( ( pParticipant->ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) && ( pEchoChanEntry->fCopyEventCreated == FALSE ) ) + { + /* The copy event has not been created, create it once for the life of the participant on the bridge. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pEchoChanEntry->usSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= pEchoChanEntry->usExtraSinTsiMemIndex; + WriteParams.usWriteData |= pEchoChanEntry->TdmConfig.bySinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pEchoChanEntry->usSinSoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now insert the Sin copy event into the list. */ + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + pEchoChanEntry->usSinCopyEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY, + f_usChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + pEchoChanEntry->fCopyEventCreated = TRUE; + } + + /* Search through the list of API channel entry for the ones onto this bridge. */ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + /* Channel reserved? */ + if ( ( usChannelIndex != f_usChanIndex ) && ( pTempEchoChanEntry->fReserved == TRUE ) ) + { + /* On current bridge? */ + if ( pTempEchoChanEntry->usBridgeIndex == pEchoChanEntry->usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if this participant can hear us. */ + if ( ( pTempParticipant->ulListenerMask & ( 0x1 << pParticipant->ulListenerMaskIndex ) ) == 0x0 ) + { + /* Then create/update this channel's mixer. */ + ulResult = Oct6100ApiBridgeAddParticipantToChannel( + f_pApiInstance, + pEchoChanEntry->usBridgeIndex, + f_usChanIndex, + usChannelIndex, + pTempParticipant->ausLoadOrAccumulateEventIndex[ pParticipant->ulListenerMaskIndex ], + pTempEchoChanEntry->usSubStoreEventIndex, + pTempEchoChanEntry->usSinCopyEventIndex, + pParticipant->ulInputPort, + pTempParticipant->ulInputPort ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the Rin silence event can be cleared now that the */ + /* channel has unmuted. */ + if ( ( pTempParticipant->fFlexibleMixerCreated == TRUE ) + && ( pTempEchoChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) ) + { + /* Remove the event from the list. */ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pTempEchoChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pTempEchoChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_DF; + + pTempEchoChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + } + } + } + } + } + else /* if ( f_fFlexibleConfBridge == FALSE ) */ + { + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLoadEventEntry, f_usLoadEventIndex ); + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pSubStoreEventEntry, f_usSubStoreEventIndex ); + + /*=======================================================================*/ + /* Program the Load event. */ + + /* Before reactivating this event, check what type of event this event must be. */ + if ( f_usLoadEventIndex == pBridgeEntry->usFirstLoadEventPtr || + pBridgeEntry->usLoadIndex == cOCT6100_INVALID_INDEX ) + { + /* This event must become a Load event. */ + usLoadEventType = cOCT6100_MIXER_CONTROL_MEM_LOAD; + pBridgeEntry->usLoadIndex = f_usLoadEventIndex; + } + + usTempEventIndex = pBridgeEntry->usFirstLoadEventPtr; + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex ); + + ulLoopCount = 0; + + while( pTempEntry->usEventType != cOCT6100_MIXER_CONTROL_MEM_SUB_STORE && + pTempEntry->usEventType != cOCT6100_MIXER_CONTROL_MEM_STORE ) + { + if ( pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_LOAD ) + { + usPreviousLoadIndex = usTempEventIndex; + } + + /* Check if the previous load event is before or after the event about to be unmuted. */ + if ( pTempEntry->usNextEventPtr == f_usLoadEventIndex ) + { + if ( usPreviousLoadIndex == cOCT6100_INVALID_INDEX ) + { + /* We did not find a load event before our node, this mean this one */ + /* is about to become the new load event. */ + usLoadEventType = cOCT6100_MIXER_CONTROL_MEM_LOAD; + } + } + + /* Go to the next entry into the list. */ + usTempEventIndex = pTempEntry->usNextEventPtr; + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex ); + + ulLoopCount++; + if ( ulLoopCount == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_FATAL_9B; + } + + /* Now program the current event node. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usLoadEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = usLoadEventType; + + /* If we have an extra Sin copy event, we know we are using the Sout port as a source. */ + if ( pEchoChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Sout source */ + WriteParams.usWriteData |= pEchoChanEntry->usSinSoutTsiMemIndex; + } + else + { + /* Rin source */ + WriteParams.usWriteData |= pEchoChanEntry->usRinRoutTsiMemIndex; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the software event to reflect the hardware. */ + pLoadEventEntry->usEventType = usLoadEventType; + + /* Check if we need to change another node. */ + if ( usLoadEventType == cOCT6100_MIXER_CONTROL_MEM_LOAD ) + { + if ( usPreviousLoadIndex != cOCT6100_INVALID_INDEX ) + { + /* Now program the old load event. */ + ReadParams.ulReadAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usPreviousLoadIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + WriteParams.usWriteData = (UINT16)(( usReadData & 0x1FFF ) | cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the software event to reflect the hardware. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usPreviousLoadIndex ); + pTempEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE; + } + } + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Program the Substract and store event. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_SUB_STORE; + /* If we have an extra Sin copy event, we know we are using the Sout port as a source. */ + if ( pEchoChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Sout port source */ + WriteParams.usWriteData |= pEchoChanEntry->TdmConfig.bySoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + WriteParams.usWriteData |= pEchoChanEntry->usSinSoutTsiMemIndex; + } + else + { + /* Rin port source */ + WriteParams.usWriteData |= pEchoChanEntry->TdmConfig.byRinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + WriteParams.usWriteData |= pEchoChanEntry->usRinRoutTsiMemIndex; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pEchoChanEntry->usRinRoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the software event to reflect the hardware. */ + pSubStoreEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_SUB_STORE; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Check if have to remove silence load event. */ + + if ( pBridgeEntry->usSilenceLoadEventPtr != cOCT6100_INVALID_INDEX ) + { + if ( pBridgeEntry->usSilenceLoadEventPtr == f_usLoadEventIndex ) + { + /* Clear the silence load event ptr. */ + pBridgeEntry->usSilenceLoadEventPtr = cOCT6100_INVALID_INDEX; + } + } + } + + /* Update the channel entry API structure */ + pEchoChanEntry->fMute = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeDominantSpeakerSetSer + +Description: This function sets the dominant speaker of a bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to + keep the present state of the chip and all its + resources. + +f_pConfBridgeDominant Pointer to conference bridge dominant speaker + structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeDominantSpeakerSetSer +UINT32 Oct6100ConfBridgeDominantSpeakerSetSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET f_pConfBridgeDominantSpeaker ) +{ + UINT16 usChanIndex; + UINT16 usBridgeIndex; + UINT32 ulResult; + + /* Check the validity of the channel handle given. */ + ulResult = Oct6100ApiCheckBridgeDominantSpeakerParams( f_pApiInstance, f_pConfBridgeDominantSpeaker, &usChanIndex, &usBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Modify all resources needed by the conference bridge. */ + ulResult = Oct6100ApiUpdateBridgeDominantSpeakerResources( f_pApiInstance, usChanIndex, usBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckBridgeDominantSpeakerParams + +Description: Check the validity of the channel given for setting the + dominant speaker. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_pConfBridgeDominant Pointer to conference bridge channel dominant speaker structure. +f_pusChannelIndex Pointer to a channel index. +f_pusChannelIndex Pointer to a bridge index. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckBridgeDominantSpeakerParams +UINT32 Oct6100ApiCheckBridgeDominantSpeakerParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET f_pConfBridgeDominantSpeaker, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT16 f_pusBridgeIndex ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + tPOCT6100_API_CHANNEL pEchoChanEntry; + UINT32 ulEntryOpenCnt; + BOOL fCheckEntryOpenCnt = FALSE; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges == 0 ) + return cOCT6100_ERR_CONF_BRIDGE_DISABLED; + + if ( f_pConfBridgeDominantSpeaker->ulChannelHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + /*=====================================================================*/ + /* Check the channel handle. */ + + if ( f_pConfBridgeDominantSpeaker->ulChannelHndl != cOCT6100_CONF_NO_DOMINANT_SPEAKER_HNDL ) + { + if ( (f_pConfBridgeDominantSpeaker->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + *f_pusChannelIndex = (UINT16)( f_pConfBridgeDominantSpeaker->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChanEntry, *f_pusChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeDominantSpeaker->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + /* Check if the channel is bound to a conference bridge. */ + if ( pEchoChanEntry->usBridgeIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHAN_NOT_ON_BRIDGE; + + /* Check if the NLP is enabled on this channel. */ + if ( pEchoChanEntry->VqeConfig.fEnableNlp == FALSE ) + return cOCT6100_ERR_CONF_BRIDGE_NLP_MUST_BE_ENABLED; + + /* Check if conferencing noise reduction is enabled on this channel. */ + if ( pEchoChanEntry->VqeConfig.fSoutConferencingNoiseReduction == FALSE ) + return cOCT6100_ERR_CONF_BRIDGE_CNR_MUST_BE_ENABLED; + + /* Check if this is a tap channel. If it is, it will never be the dominant speaker! */ + if ( pEchoChanEntry->fTap == TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_ALWAYS_MUTE; + + /* Set the bridge index. */ + *f_pusBridgeIndex = pEchoChanEntry->usBridgeIndex; + } + else + { + /* Set this such that there is no dominant speaker on this conference bridge. */ + *f_pusChannelIndex = cOCT6100_CONF_DOMINANT_SPEAKER_UNASSIGNED; + + /* Check the conference bridge handle. */ + if ( (f_pConfBridgeDominantSpeaker->ulConfBridgeHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CONF_BRIDGE ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + /* Set the bridge index. */ + *f_pusBridgeIndex = (UINT16)( f_pConfBridgeDominantSpeaker->ulConfBridgeHndl & cOCT6100_HNDL_INDEX_MASK ); + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeDominantSpeaker->ulConfBridgeHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + fCheckEntryOpenCnt = TRUE; + } + + /*=====================================================================*/ + + /*=====================================================================*/ + + if ( *f_pusBridgeIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, *f_pusBridgeIndex ) + + /* Check for errors. */ + if ( pBridgeEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( fCheckEntryOpenCnt == TRUE ) + { + if ( ulEntryOpenCnt != pBridgeEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + } + + /*=====================================================================*/ + /* Check if dominant speaker is supported in this firmware version. */ + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fDominantSpeakerEnabled == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_DOMINANT_SPEAKER; + + /*=====================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateBridgeDominantSpeakerResources + +Description: Modify the conference bridge such that the new dominant + speaker is the one specified by the index. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usChanIndex Index of the channel to be set as the dominant speaker. +f_usBridgeIndex Index of the bridge where this channel is on. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateBridgeDominantSpeakerResources +UINT32 Oct6100ApiUpdateBridgeDominantSpeakerResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChanIndex, + IN UINT16 f_usBridgeIndex ) +{ + tPOCT6100_API_CHANNEL pEchoChanEntry; + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + + UINT16 usChannelIndex; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get the bridge entry for this channel. */ + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, f_usBridgeIndex ) + + /* Set the dominant speaker index for all channels in this conference. */ + + /* Search through the list of API channel entry for the ones on to this bridge.*/ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, usChannelIndex ); + + if ( pEchoChanEntry->fReserved == TRUE ) + { + if ( pEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + /* If we are unsetting the dominant speaker, of if it is not our channel index. */ + if ( ( f_usChanIndex == cOCT6100_CONF_DOMINANT_SPEAKER_UNASSIGNED ) + || ( f_usChanIndex != usChannelIndex ) ) + { + ulResult = Oct6100ApiBridgeSetDominantSpeaker( f_pApiInstance, usChannelIndex, f_usChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + } + + /* Make sure this channel is disabled. */ + if ( f_usChanIndex != cOCT6100_CONF_DOMINANT_SPEAKER_UNASSIGNED ) + { + ulResult = Oct6100ApiBridgeSetDominantSpeaker( f_pApiInstance, f_usChanIndex, cOCT6100_CONF_DOMINANT_SPEAKER_UNASSIGNED ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Save this in the conference bridge structure. */ + /* This will be needed later when removing the channel. */ + pBridgeEntry->fDominantSpeakerSet = TRUE; + pBridgeEntry->usDominantSpeakerChanIndex = f_usChanIndex; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeMaskChangeSer + +Description: This function changes the mask of flexible bridge + participant. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to + keep the present state of the chip and all its + resources. + +f_pConfBridgeMaskChange Pointer to conference bridge participant mask + change structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeMaskChangeSer +UINT32 Oct6100ConfBridgeMaskChangeSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_MASK_CHANGE f_pConfBridgeMaskChange ) +{ + UINT16 usChanIndex; + UINT16 usBridgeIndex; + UINT32 ulResult; + UINT32 ulNewParticipantMask; + + /* Check the validity of the channel handle given. */ + ulResult = Oct6100ApiCheckBridgeMaskChangeParams( f_pApiInstance, f_pConfBridgeMaskChange, &usChanIndex, &usBridgeIndex, &ulNewParticipantMask ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update all resources needed by the new mask. */ + ulResult = Oct6100ApiUpdateMaskModifyResources( f_pApiInstance, usBridgeIndex, usChanIndex, ulNewParticipantMask ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Commit the changes to the chip's internal memories. */ + ulResult = Oct6100ApiBridgeUpdateMask( f_pApiInstance, usBridgeIndex, usChanIndex, ulNewParticipantMask ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckBridgeMaskChangeParams + +Description: Check the validity of the channel given for setting the + mask. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeMaskChange Pointer to conference bridge channel mask change structure. +f_pusChannelIndex Pointer to a channel index. +f_pusBridgeIndex Pointer to a bridge index. +f_pulNewParticipantMask New mask to apply for this participant. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckBridgeMaskChangeParams +UINT32 Oct6100ApiCheckBridgeMaskChangeParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_MASK_CHANGE f_pConfBridgeMaskChange, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT16 f_pusBridgeIndex, + OUT PUINT32 f_pulNewParticipantMask ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + tPOCT6100_API_CHANNEL pEchoChanEntry; + UINT32 ulEntryOpenCnt; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges == 0 ) + return cOCT6100_ERR_CONF_BRIDGE_DISABLED; + + if ( f_pConfBridgeMaskChange->ulChannelHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + /*=====================================================================*/ + /* Check the channel handle.*/ + + if ( (f_pConfBridgeMaskChange->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + *f_pusChannelIndex = (UINT16)( f_pConfBridgeMaskChange->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChanEntry, *f_pusChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeMaskChange->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + /* Check if the channel is bound to a conference bridge. */ + if ( pEchoChanEntry->usBridgeIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHAN_NOT_ON_BRIDGE; + + /* Set the bridge index. */ + *f_pusBridgeIndex = pEchoChanEntry->usBridgeIndex; + + /*=====================================================================*/ + + /*=====================================================================*/ + + if ( ( *f_pusBridgeIndex == cOCT6100_INVALID_INDEX ) + || ( *f_pusBridgeIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges ) ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, *f_pusBridgeIndex ) + + /* Check for errors. */ + if ( pBridgeEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + + /* Check if this is bridge is a flexible conference bridge. */ + if ( pBridgeEntry->fFlexibleConferencing == FALSE ) + return cOCT6100_ERR_CONF_BRIDGE_SIMPLE_BRIDGE; + + /*=====================================================================*/ + + /* Return new mask to apply. */ + *f_pulNewParticipantMask = f_pConfBridgeMaskChange->ulNewListenerMask; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateMaskModifyResources + +Description: Modify/reserve all resources needed for the modification of + the participant's mask. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usBridgeIndex Bridge index of the bridge where this channel is residing. +f_usChanIndex Channel index of the channel to be modified. +f_ulNewListenerMask New mask to apply to the selected participant. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateMaskModifyResources +UINT32 Oct6100ApiUpdateMaskModifyResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChanIndex, + IN UINT32 f_ulNewListenerMask ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_CHANNEL pTempEchoChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pParticipant; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pTempParticipant; + + UINT32 ulResult = cOCT6100_ERR_OK; + UINT32 ulTempVar; + UINT32 ulOldListenerMask; + UINT16 usChannelIndex; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ) + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pParticipant, pChanEntry->usFlexConfParticipantIndex ); + + /* Must travel all clients of this conference and reserve a load or accumulate event for */ + /* all participants which could not hear us but now can. While at it, check for events that */ + /* could be released, for example a participant that we cannot hear anymore. */ + + ulOldListenerMask = pParticipant->ulListenerMask; + + /* Search through the list of API channel entry for the ones on to this bridge.*/ + for ( usChannelIndex = 0; ( usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels ) && ( ulResult == cOCT6100_ERR_OK ) ; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + /* Channel reserved? */ + if ( ( usChannelIndex != f_usChanIndex ) && ( pTempEchoChanEntry->fReserved == TRUE ) ) + { + /* On current bridge? */ + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if we can now hear this participant, but could not before. */ + if ( ( ( f_ulNewListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) == 0x0 ) + && ( ( ulOldListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) != 0x0 ) ) + { + /* Must reserve a load or accumulate entry mixer event here! */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, &pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ] ); + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Most probably, the hardware is out of mixer events. */ + break; + } + } + + /* Check if we can now NOT hear this participant, but could before. */ + if ( ( ( f_ulNewListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) != 0x0 ) + && ( ( ulOldListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) == 0x0 ) ) + { + /* Must release the load or accumulate entry mixer event. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ] ); + if ( ulResult != cOCT6100_ERR_OK ) + { + break; + } + } + } + } + } + + /* If an error is returned, make sure everything is cleaned up properly. */ + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Search through the list of API channel entry for the ones on to this bridge.*/ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + /* Channel reserved? */ + if ( ( usChannelIndex != f_usChanIndex ) && ( pTempEchoChanEntry->fReserved == TRUE ) ) + { + /* On current bridge? */ + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if we can now hear this participant, but could not before. */ + if ( ( ( f_ulNewListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) == 0x0 ) + && ( ( ulOldListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) != 0x0 ) ) + { + /* If the load or event entry in the mixer memory was reserved. */ + if ( pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ] != cOCT6100_INVALID_INDEX ) + { + /* Must release the load or accumulate entry mixer event. */ + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ] ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + + pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ] = cOCT6100_INVALID_INDEX; + } + } + + /* Check if we can now NOT hear this participant, but could before. */ + if ( ( ( f_ulNewListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) != 0x0 ) + && ( ( ulOldListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) == 0x0 ) ) + { + /* If the load or event entry in the mixer memory was reserved. */ + if ( pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ] == cOCT6100_INVALID_INDEX ) + { + /* Must release the load or accumulate entry mixer event. */ + ulTempVar = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, &( pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ] ) ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + } + } + } + } + + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBridgeUpdateMask + +Description: Update the participant's mask. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_usBridgeIndex Bridge index of the bridge where this channel is residing. +f_usChanIndex Channel index of the channel to be modified. +f_ulNewListenerMask New mask to apply to the selected participant. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBridgeUpdateMask +UINT32 Oct6100ApiBridgeUpdateMask( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChanIndex, + IN UINT32 f_ulNewListenerMask ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_CHANNEL pTempEchoChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pParticipant; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pTempParticipant; + tOCT6100_WRITE_PARAMS WriteParams; + + UINT32 ulResult; + UINT32 ulOldListenerMask; + UINT16 usChannelIndex; + + UINT16 ausMutePortChannelIndexes[ cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE ]; + UINT32 ulMutePortChannelIndex; + + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + ausMutePortChannelIndexes[ ulMutePortChannelIndex ] = cOCT6100_INVALID_INDEX; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ) + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pParticipant, pChanEntry->usFlexConfParticipantIndex ); + + ulOldListenerMask = pParticipant->ulListenerMask; + + /* Search through the list of API channel entry for the ones onto this bridge. */ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + /* Channel reserved? */ + if ( ( usChannelIndex != f_usChanIndex ) && ( pTempEchoChanEntry->fReserved == TRUE ) ) + { + /* On current bridge? */ + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if we can now hear this participant, but could not before. */ + if ( ( pTempEchoChanEntry->fMute == FALSE ) + && ( ( f_ulNewListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) == 0x0 ) + && ( ( ulOldListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) != 0x0 ) ) + { + /* First create/update the current channel's mixer. */ + ulResult = Oct6100ApiBridgeAddParticipantToChannel( + f_pApiInstance, + f_usBridgeIndex, + usChannelIndex, + f_usChanIndex, + pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ], + pChanEntry->usSubStoreEventIndex, + pChanEntry->usSinCopyEventIndex, + pTempParticipant->ulInputPort, + pParticipant->ulInputPort ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( pParticipant->fFlexibleMixerCreated == TRUE ) + { + /* Check if the Rin silence event can be cleared now that the */ + /* channel has been added to a conference. */ + if ( pChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_DF; + + pChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + } + } + + /* Check if we can now NOT hear this participant, but could before. */ + if ( ( ( f_ulNewListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) != 0x0 ) + && ( ( ulOldListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) == 0x0 ) + && ( pParticipant->fFlexibleMixerCreated == TRUE ) + && ( pTempEchoChanEntry->fMute == FALSE ) ) + { + /* First update the current channel's mixer. */ + ulResult = Oct6100ApiBridgeRemoveParticipantFromChannel( + f_pApiInstance, + f_usBridgeIndex, + usChannelIndex, + f_usChanIndex, + TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( pParticipant->fFlexibleMixerCreated == FALSE ) + { + /* Remember to mute the port on this channel. */ + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + { + if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == f_usChanIndex ) + { + break; + } + else if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == cOCT6100_INVALID_INDEX ) + { + ausMutePortChannelIndexes[ ulMutePortChannelIndex ] = f_usChanIndex; + break; + } + } + } + } + + /* Clear the load or accumulate event index for this participant. */ + if ( ( ( f_ulNewListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) != 0x0 ) + && ( ( ulOldListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) == 0x0 ) ) + { + pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ] = cOCT6100_INVALID_INDEX; + } + } + } + + /* Travel through the channels that were heard by the participant removed and check if their Rin port must be muted. */ + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + { + if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, ausMutePortChannelIndexes[ ulMutePortChannelIndex ] ); + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + if ( pTempParticipant->fFlexibleMixerCreated == FALSE ) + { + /* Check if the Rin port must be muted on this channel. */ + ulResult = Oct6100ApiMutePorts( + f_pApiInstance, + ausMutePortChannelIndexes[ ulMutePortChannelIndex ], + pTempEchoChanEntry->usRinTsstIndex, + pTempEchoChanEntry->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else /* if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == cOCT6100_INVALID_INDEX ) */ + { + /* No more channels to check for muting. */ + break; + } + } + } + + /* Configure the SIN copy mixer entry and memory - if using the SOUT port. */ + if ( pParticipant->ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + if ( pChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pChanEntry->usSinTsstIndex, + pChanEntry->usExtraSinTsiMemIndex, + pChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* If the silence TSI is loaded on this port, update with the extra sin TSI. */ + if ( pChanEntry->usSinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pChanEntry->usSinSilenceEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pChanEntry->usExtraSinTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Configure the RIN copy mixer entry and memory - if using the RIN port. */ + if ( pParticipant->ulInputPort == cOCT6100_CHANNEL_PORT_RIN ) + { + if ( pChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pChanEntry->usRinTsstIndex, + pChanEntry->usExtraRinTsiMemIndex, + pChanEntry->TdmConfig.byRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Save the new mask permanently in the API instance. */ + pParticipant->ulListenerMask = f_ulNewListenerMask; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeGetStatsSer + +Description: This function returns the statistics from the specified bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeStats Pointer to conference bridge stats structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeGetStatsSer +UINT32 Oct6100ConfBridgeGetStatsSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_STATS f_pConfBridgeStats ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + UINT16 usConfBridgeIndex; + UINT32 ulEntryOpenCnt; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges == 0 ) + return cOCT6100_ERR_CONF_BRIDGE_DISABLED; + + /*=====================================================================*/ + /* Check the conference bridge handle. */ + + /* Check the provided handle. */ + if ( (f_pConfBridgeStats->ulConfBridgeHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CONF_BRIDGE ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + usConfBridgeIndex = (UINT16)( f_pConfBridgeStats->ulConfBridgeHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( usConfBridgeIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, usConfBridgeIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeStats->ulConfBridgeHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pBridgeEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( ulEntryOpenCnt != pBridgeEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + /*=====================================================================*/ + + /* Return the stats.*/ + f_pConfBridgeStats->ulNumChannels = pBridgeEntry->usNumClients; + f_pConfBridgeStats->ulNumTappedChannels = pBridgeEntry->usNumTappedClients; + f_pConfBridgeStats->fFlexibleConferencing = pBridgeEntry->fFlexibleConferencing; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveBridgeEntry + +Description: Reserves a free entry in the Bridge list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_pusBridgeIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveBridgeEntry +UINT32 Oct6100ApiReserveBridgeEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusBridgeIndex ) +{ + PVOID pBridgeAlloc; + UINT32 ulResult; + UINT32 ulBridgeIndex; + + mOCT6100_GET_CONF_BRIDGE_ALLOC_PNT( f_pApiInstance->pSharedInfo, pBridgeAlloc ) + + ulResult = OctapiLlmAllocAlloc( pBridgeAlloc, &ulBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_CONF_BRIDGE_ALL_BUFFERS_OPEN; + else + return cOCT6100_ERR_FATAL_29; + } + + *f_pusBridgeIndex = (UINT16)( ulBridgeIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseBridgeEntry + +Description: Release an entry from the bridge list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usBridgeIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseBridgeEntry +UINT32 Oct6100ApiReleaseBridgeEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBridgeIndex ) +{ + PVOID pBridgeAlloc; + UINT32 ulResult; + + mOCT6100_GET_CONF_BRIDGE_ALLOC_PNT( f_pApiInstance->pSharedInfo, pBridgeAlloc ) + + ulResult = OctapiLlmAllocDealloc( pBridgeAlloc, f_usBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_2A; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetPrevLastSubStoreEvent + +Description: This function will search for the first valid LastSubStoreEvent + in a bridge located before the current bridge in the bridge + link list. + + If the function does not find an event before reaching the end + of the mixers list, then the event head node will be used as the + last Store or SubStore event. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pusBridgeEntry Bridge entry. +f_usBridgeFirstLoadEventPtr Load index to check against. +First valid sub store index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetPrevLastSubStoreEvent +UINT32 Oct6100ApiGetPrevLastSubStoreEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usBridgeFirstLoadEventPtr, + OUT PUINT16 f_pusLastSubStoreEventIndex ) +{ + tPOCT6100_API_MIXER_EVENT pTempMixerEntry; + UINT16 usNextEventPtr; + UINT16 usHeadEventPtr; + UINT16 usLastSubStoreEventPtr; + UINT32 ulLoopCount = 0; + UINT16 usCurrentPtr; + UINT32 ulResult = cOCT6100_ERR_OK; + + /* Since we have flexible bridges, we have to */ + /* run down the list and check for the appropriate event. */ + + /* Travel down the list for the last Store or Sub/Store event before the bridge. */ + + if ( f_pApiInstance->pSharedInfo->MixerInfo.usLastSoutCopyEventPtr == cOCT6100_INVALID_INDEX ) + { + /* The only node in the list then is the head node.*/ + usHeadEventPtr = cOCT6100_MIXER_HEAD_NODE; + } + else + { + usHeadEventPtr = f_pApiInstance->pSharedInfo->MixerInfo.usLastSoutCopyEventPtr; + } + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTempMixerEntry, usHeadEventPtr ); + usLastSubStoreEventPtr = usHeadEventPtr; + usNextEventPtr = pTempMixerEntry->usNextEventPtr; + usCurrentPtr = usHeadEventPtr; + while( usCurrentPtr != f_usBridgeFirstLoadEventPtr ) + { + if ( ( pTempMixerEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_STORE ) + || ( pTempMixerEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_SUB_STORE ) ) + { + usLastSubStoreEventPtr = usNextEventPtr; + } + + /* Next pointer. */ + usCurrentPtr = usNextEventPtr; + usNextEventPtr = pTempMixerEntry->usNextEventPtr; + + /* Check if next event pointer is valid. */ + if ( ( ( f_usBridgeFirstLoadEventPtr != usCurrentPtr ) + && ( pTempMixerEntry->usNextEventPtr == cOCT6100_INVALID_INDEX ) ) + || ( pTempMixerEntry->usNextEventPtr == cOCT6100_MIXER_HEAD_NODE ) ) + return cOCT6100_ERR_CONF_MIXER_EVENT_NOT_FOUND; + + if ( usNextEventPtr != cOCT6100_INVALID_INDEX ) + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTempMixerEntry, usNextEventPtr ); + + ulLoopCount++; + if ( ulLoopCount == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_FATAL_CA; + } + + /* Return the result to the user. */ + *f_pusLastSubStoreEventIndex = usLastSubStoreEventPtr; + + return ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetPreviousEvent + +Description: This is a recursive function, it requires an entry event index and + will run down the list until it finds the node just before the one + required. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usEntryIndex Event entry index. +f_pusBridgeEntry Bridge entry. +f_pusPreviousIndex Previous index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetPreviousEvent +UINT32 Oct6100ApiGetPreviousEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEntryIndex, + IN UINT16 f_usSearchedIndex, + IN UINT16 f_usLoopCnt, + OUT PUINT16 f_pusPreviousIndex ) +{ + tPOCT6100_API_MIXER_EVENT pCurrentEntry; + UINT32 ulResult; + + /* Get current entry to obtain the link to the previous entry. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pCurrentEntry, f_usEntryIndex ); + + /* Avoid stack overflows. */ + if ( f_usLoopCnt == cOCT6100_MAX_MIXER_EVENTS ) + return cOCT6100_ERR_FATAL_E3; + + if ( pCurrentEntry->usNextEventPtr == cOCT6100_INVALID_INDEX ) + { + /* Event not found. */ + ulResult = cOCT6100_ERR_CONF_MIXER_EVENT_NOT_FOUND; + } + else if ( pCurrentEntry->usNextEventPtr == f_usSearchedIndex ) + { + /* We found our node. */ + *f_pusPreviousIndex = f_usEntryIndex; + ulResult = cOCT6100_ERR_OK; + } + else + { + /* Keep searching.*/ + f_usLoopCnt++; + ulResult = Oct6100ApiGetPreviousEvent( f_pApiInstance, pCurrentEntry->usNextEventPtr, f_usSearchedIndex, f_usLoopCnt, f_pusPreviousIndex ); + } + + return ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBridgeSetDominantSpeaker + +Description: This function will set the index of the dominant speaker + for the channel index specified. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to + keep the present state of the chip and all its + resources. + +f_usChannelIndex Index of the channel where the API must set the + current dominant speaker for the conference. +f_usDominantSpeakerIndex Index of the channel which is the dominant + speaker in the conference. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBridgeSetDominantSpeaker +UINT32 Oct6100ApiBridgeSetDominantSpeaker( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChannelIndex, + IN UINT16 f_usDominantSpeakerIndex ) +{ + UINT32 ulBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulResult; + UINT32 ulTempData; + UINT32 ulMask; + + tPOCT6100_API_CHANNEL pEchoChanEntry; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChanEntry, f_usChannelIndex ); + + ulBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_usChannelIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanRootConfOfst; + ulFeatureBytesOffset = f_pApiInstance->pSharedInfo->MemoryMap.DominantSpeakerFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = f_pApiInstance->pSharedInfo->MemoryMap.DominantSpeakerFieldOfst.byBitOffset; + ulFeatureFieldLength = f_pApiInstance->pSharedInfo->MemoryMap.DominantSpeakerFieldOfst.byFieldSize; + + /* Retrieve the current configuration. */ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pEchoChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + ulTempData |= ( ( f_usDominantSpeakerIndex ) << ulFeatureBitOffset ); + + /* Save the new dominant speaker. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveFlexConfParticipantEntry + +Description: Reserves a free entry in the participant list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_pusParticipantIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveFlexConfParticipantEntry +UINT32 Oct6100ApiReserveFlexConfParticipantEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusParticipantIndex ) +{ + PVOID pParticipantAlloc; + UINT32 ulResult; + UINT32 ulParticipantIndex; + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ALLOC_PNT( f_pApiInstance->pSharedInfo, pParticipantAlloc ) + + ulResult = OctapiLlmAllocAlloc( pParticipantAlloc, &ulParticipantIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_ALL_BUFFERS_OPEN; + else + return cOCT6100_ERR_FATAL_29; + } + + *f_pusParticipantIndex = (UINT16)( ulParticipantIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseFlexConfParticipantEntry + +Description: Release an entry from the flexible conferencing participant + list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usParticipantIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseFlexConfParticipantEntry +UINT32 Oct6100ApiReleaseFlexConfParticipantEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usParticipantIndex ) +{ + PVOID pParticipantAlloc; + UINT32 ulResult; + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ALLOC_PNT( f_pApiInstance->pSharedInfo, pParticipantAlloc ) + + ulResult = OctapiLlmAllocDealloc( pParticipantAlloc, f_usParticipantIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_2A; + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_debug.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_debug.c new file mode 100644 index 0000000..1f4de01 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_debug.c @@ -0,0 +1,1278 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_debug.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains functions used to debug the OCT6100. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 65 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_channel_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_debug_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_debug_priv.h" +#include "oct6100_version.h" + + +/**************************** PUBLIC FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100DebugSelectChannel + +Description: This function sets the current debug channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pSelectDebugChan Pointer to select debug channel structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100DebugSelectChannelDef +UINT32 Oct6100DebugSelectChannelDef( + tPOCT6100_DEBUG_SELECT_CHANNEL f_pSelectDebugChan ) +{ + f_pSelectDebugChan->ulChannelHndl = cOCT6100_INVALID_VALUE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100DebugSelectChannel +UINT32 Oct6100DebugSelectChannel( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_DEBUG_SELECT_CHANNEL f_pSelectDebugChan ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100DebugSelectChannelSer( f_pApiInstance, f_pSelectDebugChan, TRUE ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100DebugGetData + +Description: This function retrieves the last recorded debug data. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pGetData Pointer to debug get data structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100DebugGetDataDef +UINT32 Oct6100DebugGetDataDef( + tPOCT6100_DEBUG_GET_DATA f_pGetData ) +{ + f_pGetData->ulGetDataMode = cOCT6100_DEBUG_GET_DATA_MODE_120S_LITE; + f_pGetData->ulGetDataContent = cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE; + f_pGetData->ulRemainingNumBytes = cOCT6100_INVALID_VALUE; + f_pGetData->ulTotalNumBytes = cOCT6100_INVALID_VALUE; + f_pGetData->ulMaxBytes = cOCT6100_INVALID_VALUE; + f_pGetData->ulValidNumBytes = cOCT6100_INVALID_VALUE; + f_pGetData->pbyData = NULL; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100DebugGetData +UINT32 Oct6100DebugGetData( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_DEBUG_GET_DATA f_pGetData ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100DebugGetDataSer( f_pApiInstance, f_pGetData ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100DebugSelectChannelSer + +Description: This function sets the debug channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pSelectDebugChan Pointer to a tOCT6100_DEBUG_SELECT_CHANNEL structure. +f_fCheckChannelRecording Check if channel recording is enabled or not. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100DebugSelectChannelSer +UINT32 Oct6100DebugSelectChannelSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_DEBUG_SELECT_CHANNEL f_pSelectDebugChan, + IN BOOL f_fCheckChannelRecording ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry = NULL; + tPOCT6100_API_CHANNEL pTempChanEntry; + tOCT6100_CHANNEL_OPEN TempChanOpen; + tOCT6100_WRITE_BURST_PARAMS BurstParams; + UINT16 usChanIndex = 0; + UINT32 ulEntryOpenCnt; + UINT16 ausWriteData[ 2 ]; + UINT32 ulResult; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + BurstParams.pusWriteData = ausWriteData; + + /* First release the resources reserved for the channel that was previously debugged. */ + if ( pSharedInfo->DebugInfo.usCurrentDebugChanIndex != cOCT6100_INVALID_INDEX && + pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + { + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempChanEntry, pSharedInfo->DebugInfo.usCurrentDebugChanIndex ) + + /* Release the extra TSI memory entry and reprogram the TSST control memory if required. */ + if ( pTempChanEntry->usExtraSinTsiDependencyCnt >= 1 ) + { + /*=======================================================================*/ + /* Clear memcpy operations. */ + + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSharedInfo->MixerInfo.usRecordCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + BurstParams.ulWriteLength = 2; + + ausWriteData[ 0 ] = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + ausWriteData[ 1 ] = 0x0; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSharedInfo->MixerInfo.usRecordSinEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* If we are the last dependency using the extra Sin TSI, release it */ + if ( pTempChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pTempChanEntry->usExtraSinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Do not forget to reprogram the TSST control memory. */ + if ( pTempChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pTempChanEntry->usSinTsstIndex, + pTempChanEntry->usSinSoutTsiMemIndex, + pTempChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + pTempChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + + /* XXX: What about the silence TSI usSinSilenceEventIndex ?? */ + } + + pTempChanEntry->usExtraSinTsiDependencyCnt--; + + } + } + + /* Set the new parameters. */ + if ( f_pSelectDebugChan->ulChannelHndl != cOCT6100_INVALID_HANDLE ) + { + /* Check the provided handle. */ + if ( (f_pSelectDebugChan->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_DEBUG_CHANNEL_INVALID_HANDLE; + + usChanIndex = (UINT16)( f_pSelectDebugChan->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( usChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_DEBUG_CHANNEL_INVALID_HANDLE; + + if ( f_fCheckChannelRecording == TRUE ) + { + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == FALSE ) + return cOCT6100_ERR_DEBUG_CHANNEL_RECORDING_DISABLED; + } + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, usChanIndex ); + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pSelectDebugChan->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + + /* First program the mixer entry if the user wants to record. */ + /* Check if the API needs to reserve an extra TSI memory to load the SIN signal. */ + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + { + /* Reserve the extra Sin TSI memory if it was not already reserved. */ + if ( pChanEntry->usExtraSinTsiMemIndex == cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, &pChanEntry->usExtraSinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reprogram the TSST control memory accordingly. */ + if ( pChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pChanEntry->usSinTsstIndex, + pChanEntry->usExtraSinTsiMemIndex, + pChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* XXX: What about the silence TSI usSinSilenceEventIndex ?? */ + } + + + /*=======================================================================*/ + /* Program the Sout Copy event. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSharedInfo->MixerInfo.usRecordCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + BurstParams.ulWriteLength = 2; + + ausWriteData[ 0 ] = cOCT6100_MIXER_CONTROL_MEM_COPY; + ausWriteData[ 0 ] |= pChanEntry->usSinSoutTsiMemIndex; + ausWriteData[ 0 ] |= pChanEntry->TdmConfig.bySinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + ausWriteData[ 1 ] = (UINT16)( pSharedInfo->DebugInfo.usRecordRinRoutTsiMemIndex ); + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*=======================================================================*/ + + /*=======================================================================*/ + /* Program the Sin copy event. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSharedInfo->MixerInfo.usRecordSinEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + BurstParams.ulWriteLength = 2; + + ausWriteData[ 0 ] = cOCT6100_MIXER_CONTROL_MEM_COPY; + ausWriteData[ 0 ] |= pChanEntry->usExtraSinTsiMemIndex; + ausWriteData[ 0 ] |= pChanEntry->TdmConfig.bySinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + ausWriteData[ 1 ] = pChanEntry->usSinSoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*=======================================================================*/ + + pChanEntry->usExtraSinTsiDependencyCnt++; + } + } + else + { + /* Set the index to invalid to deactivate the recording. */ + usChanIndex = cOCT6100_INVALID_INDEX; + } + + /* Set law of newly selected hot channel. */ + if ( ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + && ( f_pSelectDebugChan->ulChannelHndl != cOCT6100_INVALID_HANDLE ) + && ( pChanEntry != NULL ) ) + { + /* Set the PCM law of the debug channel. */ + /* Let's program the channel memory. */ + Oct6100ChannelOpenDef( &TempChanOpen ); + + TempChanOpen.ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_HT_RESET; /* Activate the channel. */ + TempChanOpen.VqeConfig.fEnableNlp = FALSE; + TempChanOpen.VqeConfig.ulComfortNoiseMode = cOCT6100_COMFORT_NOISE_NORMAL; + TempChanOpen.VqeConfig.fSinDcOffsetRemoval = FALSE; + TempChanOpen.VqeConfig.fRinDcOffsetRemoval = FALSE; + TempChanOpen.VqeConfig.lDefaultErlDb = 0; + + /* Use the law of the channel being recorded. */ + TempChanOpen.TdmConfig.ulRinPcmLaw = pChanEntry->TdmConfig.byRinPcmLaw; + TempChanOpen.TdmConfig.ulSinPcmLaw = pChanEntry->TdmConfig.bySinPcmLaw; + TempChanOpen.TdmConfig.ulRoutPcmLaw = pChanEntry->TdmConfig.byRoutPcmLaw; + TempChanOpen.TdmConfig.ulSoutPcmLaw = pChanEntry->TdmConfig.bySoutPcmLaw; + + ulResult = Oct6100ApiWriteDebugChanMemory( f_pApiInstance, + &TempChanOpen.TdmConfig, + &TempChanOpen.VqeConfig, + &TempChanOpen, + pSharedInfo->DebugInfo.usRecordChanIndex, + pSharedInfo->DebugInfo.usRecordMemIndex, + pSharedInfo->DebugInfo.usRecordRinRoutTsiMemIndex, + pSharedInfo->DebugInfo.usRecordSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + ausWriteData[ 0 ] = 0x0; + ausWriteData[ 1 ] = (UINT16)(( usChanIndex >> 0) & 0xFFFF); + + /* Write the channel number into the Matrix hot channel field.*/ + BurstParams.ulWriteAddress = pSharedInfo->DebugInfo.ulHotChannelSelectBaseAddress; + BurstParams.pusWriteData = ausWriteData; + BurstParams.ulWriteLength = 2; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + pSharedInfo->DebugInfo.usCurrentDebugChanIndex = usChanIndex; + + /* Cancel data dump request, if there was one. */ + pSharedInfo->DebugInfo.fDebugDataBeingDumped = FALSE; + pSharedInfo->DebugInfo.ulDebugDataTotalNumBytes = cOCT6100_INVALID_VALUE; + + /* Call from remote client. */ + if ( f_fCheckChannelRecording == FALSE ) + { + /* If the user has not activated recording, let the remote client know. */ + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == FALSE ) + return cOCT6100_ERR_DEBUG_RC_CHANNEL_RECORDING_DISABLED; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100DebugGetDataSer + +Description: This function retrieves the latest recorded debug data. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pGetData Pointer to a tOCT6100_DEBUG_GET_DATA structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100DebugGetDataSer +UINT32 Oct6100DebugGetDataSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_DEBUG_GET_DATA f_pGetData ) +{ + + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry = NULL; + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_BURST_PARAMS ReadBurstParams; + tOCT6100_WRITE_BURST_PARAMS WriteBurstParams; + + UINT16 ausWriteData[ 2 ]; + UINT16 usReadData; + UINT16 usDebugEventReadPtr; + UINT16 usTempNumEvents; + + UINT32 ulResult; + UINT32 ulToneEventIndex; + UINT32 ulReadPointer; + UINT32 ulUserBufWriteIndex = 0; + UINT32 ulTimestamp; + UINT32 ulDebugEventIndex = 0; + UINT32 ulStreamIndex; + UINT32 ulPcmSampleIndex; + UINT32 ulNumAfEvents; + UINT32 ulNumReads = 0; + UINT32 ulTempIndex; + UINT32 ulCopyIndex; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulStreamIndexMin; + UINT32 ulStreamIndexMax; + UINT32 ulTempData; + UINT32 ulMask; + BOOL fResetRemainingDataFlag = FALSE; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + ReadBurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadBurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + WriteBurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteBurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Check all user parameters. */ + + /* Check if channel recording is enabled. */ + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == FALSE ) + return cOCT6100_ERR_DEBUG_CHANNEL_RECORDING_DISABLED; + + /* Check if a current debugging channel has been selected. */ + /* If not, the user has not yet called Oct6100DebugSelectChannel. */ + if ( pSharedInfo->DebugInfo.usCurrentDebugChanIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_DEBUG_RECORD_NO_CHAN_SELECTED; + + /* Check that the user supplied a valid max bytes value. */ + if ( f_pGetData->ulMaxBytes == cOCT6100_INVALID_VALUE ) + return cOCT6100_ERR_DEBUG_GET_DATA_MAX_BYTES; + + /* Data buffer must be aligned on 1024 bytes. */ + if ( ( f_pGetData->ulMaxBytes % 1024 ) != 0 ) + return cOCT6100_ERR_DEBUG_GET_DATA_MAX_BYTES; + + /* Check that the user provided the required memory to transfer the information. */ + if ( f_pGetData->pbyData == NULL ) + return cOCT6100_ERR_DEBUG_GET_DATA_PTR_INVALID; + + /* Check dump type. */ + if ( ( f_pGetData->ulGetDataMode != cOCT6100_DEBUG_GET_DATA_MODE_16S_LITE ) + && ( f_pGetData->ulGetDataMode != cOCT6100_DEBUG_GET_DATA_MODE_120S_LITE ) + && ( f_pGetData->ulGetDataMode != cOCT6100_DEBUG_GET_DATA_MODE_16S ) + && ( f_pGetData->ulGetDataMode != cOCT6100_DEBUG_GET_DATA_MODE_120S ) ) + return cOCT6100_ERR_DEBUG_GET_DATA_MODE; + + /* Check dump content. */ + if ( ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + && ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_RIN_PCM ) + && ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_SIN_PCM ) + && ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_SOUT_PCM ) ) + return cOCT6100_ERR_DEBUG_GET_DATA_CONTENT; + + /* Check if can accomodate the 120 seconds dump. */ + if ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S_LITE ) + || ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S ) ) + { + if ( pSharedInfo->DebugInfo.ulDebugEventSize != 0x100 ) + return cOCT6100_ERR_NOT_SUPPORTED_DEBUG_DATA_MODE_120S; + } + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, pSharedInfo->DebugInfo.usCurrentDebugChanIndex ) + + /* Lets go dump the requested data. */ + + usDebugEventReadPtr = 0; + + /* Check if this is the first time this function is called since the hot channel was set. */ + if ( pSharedInfo->DebugInfo.fDebugDataBeingDumped == FALSE ) + { + /* Check that the channel is not in POWER_DOWN. When the channel is in POWER_DOWN, */ + /* the debug events are not recorded correctly in external memory. */ + if ( pChanEntry->byEchoOperationMode == cOCT6100_ECHO_OP_MODE_POWER_DOWN ) + return cOCT6100_ERR_DEBUG_CHANNEL_IN_POWER_DOWN; + + pSharedInfo->DebugInfo.fDebugDataBeingDumped = TRUE; + + /* Flag the hot channel that it must stop recording. The data is being transfered. */ + /* This also tells the remote client not to do anything right now. */ + + ReadBurstParams.ulReadAddress = pSharedInfo->DebugInfo.ulHotChannelSelectBaseAddress; + ReadBurstParams.ulReadLength = 2; + ReadBurstParams.pusReadData = pSharedInfo->DebugInfo.ausHotChannelData; + + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteBurstParams.pusWriteData = ausWriteData; + WriteBurstParams.ulWriteAddress = pSharedInfo->DebugInfo.ulHotChannelSelectBaseAddress; + WriteBurstParams.ulWriteLength = 2; + + WriteBurstParams.pusWriteData[ 0 ] = 0xFFFF; + WriteBurstParams.pusWriteData[ 1 ] = 0xFFFF; + + mOCT6100_DRIVER_WRITE_BURST_API( WriteBurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Get the maximum number of events this firmware supports from the TLVs. */ + pSharedInfo->DebugInfo.usMatrixCBMask = (UINT16)( pSharedInfo->DebugInfo.ulDebugEventSize & 0xFFFF ); + pSharedInfo->DebugInfo.usMatrixCBMask -= 1; + + /* Find out the chip log write pointer. */ + + /* Now get the current write pointer for matrix events. */ + ReadParams.pusReadData = &pSharedInfo->DebugInfo.usChipDebugEventWritePtr; + ReadParams.ulReadAddress = pSharedInfo->DebugInfo.ulMatrixWpBaseAddress + 2; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ReadParams.pusReadData = &usReadData; + + /* This write pointer might have wrapped, but we don't know for sure. */ + /* To be confident, the chip frame timestamp is read. */ + ReadParams.ulReadAddress = pSharedInfo->DebugInfo.ulMatrixTimestampBaseAddress; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulTimestamp = usReadData << 16; + + ReadParams.ulReadAddress += 2; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulTimestamp |= usReadData; + + ulTimestamp >>= 12; /* TDM time for 1 event (512 ms) */ + + /* There is a probability here (once very 6.2 days) that the timestamp is close */ + /* to 0, because it has wrapped. But still, we need a way to workaround the highly */ + /* occuring case of the chip just being opened. This will fix this problem. */ + if ( ulTimestamp < (UINT32)( pSharedInfo->DebugInfo.usMatrixCBMask + 1 ) ) + { + if ( pSharedInfo->DebugInfo.usChipDebugEventWritePtr >= 2 ) + { + /* Must trash the first 2 events. The chip is not yet ready. */ + pSharedInfo->DebugInfo.usNumEvents = (UINT16)( pSharedInfo->DebugInfo.usChipDebugEventWritePtr - 2 ); + } + else + { + pSharedInfo->DebugInfo.usNumEvents = 0x0; + } + } + else + { + pSharedInfo->DebugInfo.usNumEvents = (UINT16)( pSharedInfo->DebugInfo.usMatrixCBMask + 1 ); + + /* Account for event being created right now while the chip is running. */ + /* The event at the write pointer will be discarded. */ + if ( pSharedInfo->DebugInfo.usNumEvents > 0 ) + pSharedInfo->DebugInfo.usNumEvents--; + } + + + /* If the user only requested the last 16 seconds, cap the number of events. */ + if ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S + || f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S_LITE ) + { + /* x events to get the last 16 seconds. */ + if ( pSharedInfo->DebugInfo.usNumEvents > ( 16000 / ( pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize / 8 ) ) ) + pSharedInfo->DebugInfo.usNumEvents = (UINT16)( ( 16000 / ( pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize / 8 ) ) & 0xFFFF ); + } + + /* Make sure that all the events are pertaining to the current hot channel. */ + /* Calculate the event read pointer. */ + ulReadPointer = ( ( pSharedInfo->DebugInfo.usChipDebugEventWritePtr - pSharedInfo->DebugInfo.usNumEvents ) & pSharedInfo->DebugInfo.usMatrixCBMask ) * pSharedInfo->DebugInfo.ulDebugChanStatsByteSize; + ulReadPointer %= ( ( pSharedInfo->DebugInfo.usMatrixCBMask + 1 ) * pSharedInfo->DebugInfo.ulDebugChanStatsByteSize ); + + /* Travel through the events and throw away the bad events. */ + usTempNumEvents = pSharedInfo->DebugInfo.usNumEvents; + pSharedInfo->DebugInfo.usNumEvents = 0; + for ( ulDebugEventIndex = 0; ulDebugEventIndex < usTempNumEvents; ulDebugEventIndex ++ ) + { + /* The HOT channel index for the event is stored at offset 0xF2 (word offset) */ + + ReadParams.ulReadAddress = pSharedInfo->DebugInfo.ulMatrixBaseAddress + ulReadPointer; + ReadParams.ulReadAddress += 0xF2 * sizeof(UINT16); + ReadParams.pusReadData = &usReadData; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the current debug index is the same as the one found in the event. */ + if ( usReadData != pSharedInfo->DebugInfo.usCurrentDebugChanIndex ) + pSharedInfo->DebugInfo.usNumEvents = 0; /* As soon as we hit another channel, we reset the number of valid events. */ + else + pSharedInfo->DebugInfo.usNumEvents++; + + /* Increment read pointer to get next event. */ + ulReadPointer = ( ulReadPointer + pSharedInfo->DebugInfo.ulDebugChanStatsByteSize ) % ( ( pSharedInfo->DebugInfo.usMatrixCBMask + 1 ) * pSharedInfo->DebugInfo.ulDebugChanStatsByteSize ); + } + + /* In heavy mode, the AF log pointer is retrieved. */ + if ( ( pSharedInfo->DebugInfo.usNumEvents >= 2 ) + && ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S ) + || ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S ) ) ) + { + /* The latest AF log write pointer is at the latest matrix event. */ + ReadParams.ulReadAddress = pSharedInfo->DebugInfo.ulMatrixBaseAddress + ( ( pSharedInfo->DebugInfo.usChipDebugEventWritePtr & pSharedInfo->DebugInfo.usMatrixCBMask ) * 1024 ); + + /* To get the AF log write pointer, which is at offset pSharedInfo->ImageInfo.ulAfWritePtrByteOffset. */ + ReadParams.ulReadAddress += pSharedInfo->DebugInfo.ulAfWritePtrByteOffset; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + pSharedInfo->DebugInfo.usAfLogWritePtr = usReadData; + + /* The AF event read pointer is the AF write pointer +4096 */ + /* This will make sure we do not get mixed up and fetch events that have */ + /* just been written, but we think are old. */ + + /* To get the exact AF log pointer, the API would have to wait 512 milliseconds to make */ + /* sure logging had stopped. This is not required since missing a few last events is not */ + /* important at this point (the user knows that valid data has already been recorded). */ + pSharedInfo->DebugInfo.usLastAfLogReadPtr = (UINT16)( ( pSharedInfo->DebugInfo.usAfLogWritePtr + 4096 ) & 0xFFFF ); + + /* Note that if the chip has just been booted, some of the AF events might not be initialized. */ + } + else + { + pSharedInfo->DebugInfo.usLastAfLogReadPtr = 0; + pSharedInfo->DebugInfo.usAfLogWritePtr = 0; + } + + /* To be aligned correctly for the bursts. */ + while ( ( pSharedInfo->DebugInfo.usLastAfLogReadPtr % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE / 8 ) ) != 0 ) + pSharedInfo->DebugInfo.usLastAfLogReadPtr++; + + /* Remember the data mode for later checks. Also, the user cannot change this "mode". */ + pSharedInfo->DebugInfo.ulCurrentGetDataMode = f_pGetData->ulGetDataMode; + } + else + { + /* Check that the user did not change the current data mode. */ + if ( pSharedInfo->DebugInfo.ulCurrentGetDataMode != f_pGetData->ulGetDataMode ) + return cOCT6100_ERR_DEBUG_GET_DATA_MODE_CANNOT_CHANGE; + } + + /* Check if this is the first pass here. */ + if ( pSharedInfo->DebugInfo.ulDebugDataTotalNumBytes == cOCT6100_INVALID_VALUE ) + { + /* Calculate how many bytes of data will be returned with respect to the selected data content. */ + + /* Check what content type the user requested. */ + if ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + { + /* Remember first AF Event Read Pointer. */ + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->DebugInfo.usLastAfLogReadPtr ) & 0xFF ); + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->DebugInfo.usLastAfLogReadPtr >> 8 ) & 0xFF ); + + /* Remember the AF Event Write Pointer. */ + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->DebugInfo.usAfLogWritePtr ) & 0xFF ); + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->DebugInfo.usAfLogWritePtr >> 8 ) & 0xFF ); + + /* Remember law and hot channel */ + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( pChanEntry->TdmConfig.bySinPcmLaw | ( ( pSharedInfo->DebugInfo.usCurrentDebugChanIndex >> 2 ) & 0xFE ) ); + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( pChanEntry->TdmConfig.bySoutPcmLaw ); + + /* Insert light or heavy mode in array. */ + if ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S_LITE ) + || ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S_LITE ) ) + { + f_pGetData->pbyData[ ulUserBufWriteIndex - 1 ] |= 0x80; + } + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( pChanEntry->TdmConfig.byRinPcmLaw | ( ( pSharedInfo->DebugInfo.usCurrentDebugChanIndex & 0x1F ) << 3 ) ); + + /* Remember usNumEvents */ + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->DebugInfo.usNumEvents ) & 0xFF ); + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->DebugInfo.usNumEvents >> 8 ) & 0xFF ); + } + + /* Last indexes set to '0'! */ + pSharedInfo->DebugInfo.usLastDebugEventIndex = 0; + pSharedInfo->DebugInfo.ulLastPcmSampleIndex = 0; + + /* No tone event has been retrieved. */ + pSharedInfo->DebugInfo.usLastToneEventIndex = 0; + + /* The version strings have not yet been copied. */ + pSharedInfo->DebugInfo.fImageVersionCopied = FALSE; + pSharedInfo->DebugInfo.fApiVersionCopied = FALSE; + + /* Estimate the total size of the buffer that will be returned. */ + f_pGetData->ulTotalNumBytes = ulUserBufWriteIndex; + + /* If the full content is requested, add all the debug data. */ + if ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + { + /* Add the matrix events. */ + if ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S ) + || ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S ) ) + { + /* Heavy mode! Grab everything! */ + f_pGetData->ulTotalNumBytes += pSharedInfo->DebugInfo.usNumEvents * pSharedInfo->DebugInfo.ulDebugChanStatsByteSize; + } + else + { + /* Lite mode! Only the most important stuff. */ + f_pGetData->ulTotalNumBytes += pSharedInfo->DebugInfo.usNumEvents * pSharedInfo->DebugInfo.ulDebugChanLiteStatsByteSize; + } + + /* Add the PCM samples. */ + f_pGetData->ulTotalNumBytes += pSharedInfo->DebugInfo.usNumEvents * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize * 3; + + /* If requested, add the AF log events. */ + if ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S ) + || ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S ) ) + { + f_pGetData->ulTotalNumBytes += (UINT32)( ( pSharedInfo->DebugInfo.usAfLogWritePtr - pSharedInfo->DebugInfo.usLastAfLogReadPtr ) & 0xFFFF ) * 16; + } + + /* Add the tone events strings. */ + f_pGetData->ulTotalNumBytes += cOCT6100_TLV_MAX_TONE_NAME_SIZE * pSharedInfo->ImageInfo.byNumToneDetectors; + + /* Add the image version string. */ + f_pGetData->ulTotalNumBytes += 512; + + /* Add the API version string. */ + f_pGetData->ulTotalNumBytes += sizeof( cOCT6100_API_VERSION ); + } + else /* if ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) */ + { + /* Add one PCM stream. */ + f_pGetData->ulTotalNumBytes += pSharedInfo->DebugInfo.usNumEvents * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize; + } + + /* Save this in the instance for further calls. */ + pSharedInfo->DebugInfo.ulDebugDataTotalNumBytes = f_pGetData->ulTotalNumBytes; + + /* Calculate remaining bytes. All the bytes for now! */ + f_pGetData->ulRemainingNumBytes = f_pGetData->ulTotalNumBytes; + + /* Save this in the instance for the next calls. */ + pSharedInfo->DebugInfo.ulDebugDataRemainingNumBytes = f_pGetData->ulRemainingNumBytes; + } + else + { + f_pGetData->ulTotalNumBytes = pSharedInfo->DebugInfo.ulDebugDataTotalNumBytes; + } + + /* Calculate the event read pointer. */ + ulReadPointer = ( ( pSharedInfo->DebugInfo.usChipDebugEventWritePtr - pSharedInfo->DebugInfo.usNumEvents ) & pSharedInfo->DebugInfo.usMatrixCBMask ) * pSharedInfo->DebugInfo.ulDebugChanStatsByteSize; + + ulReadPointer += pSharedInfo->DebugInfo.ulDebugChanStatsByteSize * pSharedInfo->DebugInfo.usLastDebugEventIndex; + ulReadPointer %= ( ( pSharedInfo->DebugInfo.usMatrixCBMask + 1 ) * pSharedInfo->DebugInfo.ulDebugChanStatsByteSize ); + + if ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + { + /* Copy the debug events in the user buffer. */ + for( ulDebugEventIndex = pSharedInfo->DebugInfo.usLastDebugEventIndex; ulDebugEventIndex < pSharedInfo->DebugInfo.usNumEvents; ulDebugEventIndex ++ ) + { + ReadBurstParams.ulReadAddress = pSharedInfo->DebugInfo.ulMatrixBaseAddress + ulReadPointer; + + /* Check if we are in light or heavy mode. The burst size is not the same. */ + if ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S ) + || ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S ) ) + { + if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) >= pSharedInfo->DebugInfo.ulDebugChanStatsByteSize ) + ulNumReads = pSharedInfo->DebugInfo.ulDebugChanStatsByteSize / 2; + else + break; + } + else + { + if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) >= pSharedInfo->DebugInfo.ulDebugChanLiteStatsByteSize ) + ulNumReads = pSharedInfo->DebugInfo.ulDebugChanLiteStatsByteSize / 2; + else + break; + } + + ulTempIndex = 0; + while ( ulNumReads != 0 ) + { + if ( ulNumReads >= pSharedInfo->ChipConfig.usMaxRwAccesses ) + ReadBurstParams.ulReadLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + else + ReadBurstParams.ulReadLength = ulNumReads; + + /* Set pointer where to write data. */ + ReadBurstParams.pusReadData = pSharedInfo->MiscVars.ausSuperArray; + + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Copy data byte per byte to avoid endianess problems. */ + for ( ulCopyIndex = 0; ulCopyIndex < ReadBurstParams.ulReadLength; ulCopyIndex ++ ) + { + f_pGetData->pbyData[ ulUserBufWriteIndex + ulTempIndex + ( 2 * ulCopyIndex ) ] = (UINT8)( ReadBurstParams.pusReadData[ ulCopyIndex ] & 0xFF ); + f_pGetData->pbyData[ ulUserBufWriteIndex + ulTempIndex + ( 2 * ulCopyIndex ) + 1 ] = (UINT8)( ( ReadBurstParams.pusReadData[ ulCopyIndex ] >> 8 ) & 0xFF ); + } + + /* Update indexes, temp variables, addresses. */ + ulNumReads -= ReadBurstParams.ulReadLength; + ulTempIndex += ReadBurstParams.ulReadLength * 2; + ReadBurstParams.ulReadAddress += ReadBurstParams.ulReadLength * 2; + } + + /* Store register 0x202 in the event structure. */ + f_pGetData->pbyData[ ulUserBufWriteIndex + 255 ] = (UINT8)( pSharedInfo->IntrptManage.usRegister202h & 0xFF ); + f_pGetData->pbyData[ ulUserBufWriteIndex + 256 ] = (UINT8)( ( pSharedInfo->IntrptManage.usRegister202h >> 8 ) & 0xFF ); + + /* Increment index. */ + if ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S ) + || ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S ) ) + { + ulUserBufWriteIndex += pSharedInfo->DebugInfo.ulDebugChanStatsByteSize; + } + else + { + ulUserBufWriteIndex += pSharedInfo->DebugInfo.ulDebugChanLiteStatsByteSize; + } + + /* Increment read pointer to get next event. */ + ulReadPointer = ( ulReadPointer + pSharedInfo->DebugInfo.ulDebugChanStatsByteSize ) % ( ( pSharedInfo->DebugInfo.usMatrixCBMask + 1 ) * pSharedInfo->DebugInfo.ulDebugChanStatsByteSize ); + + /* Save in the instance that one of the events was dumped. */ + pSharedInfo->DebugInfo.usLastDebugEventIndex ++; + } + } + + /* Check if all debug events have been transfered. */ + if ( ( ulDebugEventIndex == pSharedInfo->DebugInfo.usNumEvents ) + || ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) ) + { + /* Fetch all streams per event. */ + for ( ulPcmSampleIndex = pSharedInfo->DebugInfo.ulLastPcmSampleIndex; ulPcmSampleIndex < ( (UINT32)pSharedInfo->DebugInfo.usNumEvents * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize ); ulPcmSampleIndex ++ ) + { + /* Check if enough room for this sample. */ + if ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + { + if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) < 1 ) + break; + } + else /* if ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) */ + { + if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) < 3 ) + break; + } + + /* Check if must retrieve data from external memory. */ + if ( ( ulPcmSampleIndex % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE * 2 ) ) == 0x0 ) + { + ulReadPointer = ( ( ( pSharedInfo->DebugInfo.usChipDebugEventWritePtr - pSharedInfo->DebugInfo.usNumEvents ) * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize ) & ( pSharedInfo->DebugInfo.usMatrixCBMask * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize ) ); + ulReadPointer += ( ulPcmSampleIndex / pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize ) * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize; + ulReadPointer &= ( pSharedInfo->DebugInfo.usMatrixCBMask * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize ); + ulReadPointer += ulPcmSampleIndex % pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize; + + /* Retrieve more data from external memory. */ + switch ( f_pGetData->ulGetDataContent ) + { + case cOCT6100_DEBUG_GET_DATA_CONTENT_RIN_PCM: + ulStreamIndexMin = 0; + ulStreamIndexMax = 1; + break; + case cOCT6100_DEBUG_GET_DATA_CONTENT_SIN_PCM: + ulStreamIndexMin = 1; + ulStreamIndexMax = 2; + break; + case cOCT6100_DEBUG_GET_DATA_CONTENT_SOUT_PCM: + ulStreamIndexMin = 2; + ulStreamIndexMax = 3; + break; + case cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE: + default: + ulStreamIndexMin = 0; + ulStreamIndexMax = 3; + break; + } + + for ( ulStreamIndex = ulStreamIndexMin; ulStreamIndex < ulStreamIndexMax; ulStreamIndex ++ ) + { + ReadBurstParams.ulReadAddress = pSharedInfo->MemoryMap.ulChanMainMemBase; + /* To get right channel information. */ + ReadBurstParams.ulReadAddress += ( ( pSharedInfo->DebugInfo.usRecordMemIndex + 2 ) * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->DebugInfo.ulAfEventCbByteSize; + /* To get correct stream. */ + ReadBurstParams.ulReadAddress += ( ( pSharedInfo->DebugInfo.usMatrixCBMask + 1 ) * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize * ulStreamIndex ); + /* PCM sample pointer in that stream. */ + ReadBurstParams.ulReadAddress += ulReadPointer; + + /* As much as we can for the burst. */ + ulTempIndex = 0; + ulNumReads = cOCT6100_INTERNAL_SUPER_ARRAY_SIZE; + while ( ulNumReads != 0 ) + { + if ( ulNumReads >= pSharedInfo->ChipConfig.usMaxRwAccesses ) + ReadBurstParams.ulReadLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + else + ReadBurstParams.ulReadLength = ulNumReads; + + /* Set pointer where to write data. */ + if ( ulStreamIndex == 0 ) + ReadBurstParams.pusReadData = &pSharedInfo->MiscVars.ausSuperArray[ ulTempIndex ]; + else if ( ulStreamIndex == 1 ) + ReadBurstParams.pusReadData = &pSharedInfo->MiscVars.ausSuperArray1[ ulTempIndex ]; + else /* if ( ulStreamIndex == 2 ) */ + ReadBurstParams.pusReadData = &pSharedInfo->MiscVars.ausSuperArray2[ ulTempIndex ]; + + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update indexes, temp variables, addresses. */ + ulNumReads -= ReadBurstParams.ulReadLength; + ulTempIndex += ReadBurstParams.ulReadLength; + ReadBurstParams.ulReadAddress += ReadBurstParams.ulReadLength * 2; + } + } + } + + /* We now have the stream data for all streams for 1 event. */ + /* Return what we can to the user. */ + if ( ( ulPcmSampleIndex % 2 ) == 0 ) + { + if ( ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + || ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_RIN_PCM ) ) + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 8 ) & 0xFF ); + + if ( ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + || ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_SIN_PCM ) ) + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray1[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 8 ) & 0xFF ); + + if ( ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + || ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_SOUT_PCM ) ) + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray2[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 8 ) & 0xFF ); + } + else /* if ( ulPcmSampleIndex % 2 == 1 ) */ + { + if ( ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + || ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_RIN_PCM ) ) + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 0 ) & 0xFF ); + + if ( ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + || ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_SIN_PCM ) ) + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray1[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 0 ) & 0xFF ); + + if ( ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + || ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_SOUT_PCM ) ) + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray2[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 0 ) & 0xFF ); + } + + pSharedInfo->DebugInfo.ulLastPcmSampleIndex++; + } + + /* Check if we are done dumping the PCM samples! */ + if ( pSharedInfo->DebugInfo.ulLastPcmSampleIndex == ( (UINT32)pSharedInfo->DebugInfo.usNumEvents * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize ) ) + { + if ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + { + + /* Go for the AF events. The AF events are only copied in heavy mode. */ + if ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S ) + || ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S ) ) + { + while ( pSharedInfo->DebugInfo.usLastAfLogReadPtr != pSharedInfo->DebugInfo.usAfLogWritePtr ) + { + /* Check if enough room for an event. */ + if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) < 16 ) + break; + + /* Check if must fill our buffer. */ + if ( ( pSharedInfo->DebugInfo.usLastAfLogReadPtr % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE / 8 ) ) == 0x0 ) + { + ulNumAfEvents = ( pSharedInfo->DebugInfo.usAfLogWritePtr - pSharedInfo->DebugInfo.usLastAfLogReadPtr ) & 0xFFFF; + + /* Check for the size of the available buffer. */ + if ( ulNumAfEvents > ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE / 8 ) ) + ulNumAfEvents = ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE / 8 ); + + /* Start at channel main base address. */ + ReadBurstParams.ulReadAddress = pSharedInfo->MemoryMap.ulChanMainMemBase; + /* To get right channel information. */ + ReadBurstParams.ulReadAddress += ( ( pSharedInfo->DebugInfo.usRecordMemIndex + 2 ) * pSharedInfo->MemoryMap.ulChanMainMemSize ); + /* To get the right AF log. */ + ReadBurstParams.ulReadAddress += ( pSharedInfo->DebugInfo.usLastAfLogReadPtr * 16 ); + + ulTempIndex = 0; + ulNumReads = ulNumAfEvents * 8; + + while ( ulNumReads != 0 ) + { + if ( ulNumReads >= pSharedInfo->ChipConfig.usMaxRwAccesses ) + ReadBurstParams.ulReadLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + else + ReadBurstParams.ulReadLength = ulNumReads; + + /* Set pointer where to write data. */ + ReadBurstParams.pusReadData = &pSharedInfo->MiscVars.ausSuperArray[ ulTempIndex ]; + + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update indexes, temp variables, addresses. */ + ulNumReads -= ReadBurstParams.ulReadLength; + ulTempIndex += ReadBurstParams.ulReadLength; + ReadBurstParams.ulReadAddress += ReadBurstParams.ulReadLength * 2; + } + } + + /* Copy data byte per byte to avoid endianess problems. */ + for ( ulCopyIndex = 0; ulCopyIndex < 8; ulCopyIndex ++ ) + { + f_pGetData->pbyData[ ulUserBufWriteIndex + ( 2 * ulCopyIndex ) ] = (UINT8)( pSharedInfo->MiscVars.ausSuperArray[ ( ( pSharedInfo->DebugInfo.usLastAfLogReadPtr % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE / 8 ) ) * 8 ) + ulCopyIndex ] & 0xFF ); + f_pGetData->pbyData[ ulUserBufWriteIndex + ( 2 * ulCopyIndex ) + 1 ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray[ ( ( pSharedInfo->DebugInfo.usLastAfLogReadPtr % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE / 8 ) ) * 8 ) + ulCopyIndex ] >> 8 ) & 0xFF ); + } + + ulUserBufWriteIndex += 16; + + /* Increment AF log read ptr. */ + pSharedInfo->DebugInfo.usLastAfLogReadPtr = (UINT16)(( pSharedInfo->DebugInfo.usLastAfLogReadPtr + 1 ) & 0xFFFF ); + } + } + + /* Check if we are done with the AF events. */ + if ( pSharedInfo->DebugInfo.usLastAfLogReadPtr == pSharedInfo->DebugInfo.usAfLogWritePtr ) + { + /* Insert the tone event information. */ + for ( ulToneEventIndex = pSharedInfo->DebugInfo.usLastToneEventIndex; ulToneEventIndex < pSharedInfo->ImageInfo.byNumToneDetectors; ulToneEventIndex++ ) + { + if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) < cOCT6100_TLV_MAX_TONE_NAME_SIZE ) + break; + + Oct6100UserMemCopy( &f_pGetData->pbyData[ ulUserBufWriteIndex ], pSharedInfo->ImageInfo.aToneInfo[ ulToneEventIndex ].aszToneName, cOCT6100_TLV_MAX_TONE_NAME_SIZE ); + + ulUserBufWriteIndex += cOCT6100_TLV_MAX_TONE_NAME_SIZE; + + pSharedInfo->DebugInfo.usLastToneEventIndex++; + } + + /* If all the tone information has been copied. */ + if ( ulToneEventIndex == pSharedInfo->ImageInfo.byNumToneDetectors ) + { + /* Copy the image version. */ + if ( pSharedInfo->DebugInfo.fImageVersionCopied == FALSE ) + { + if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) >= 512 ) + { + Oct6100UserMemCopy( &f_pGetData->pbyData[ ulUserBufWriteIndex ], pSharedInfo->ImageInfo.szVersionNumber, 512 ); + + /* Get PLL jitter count from external memory. */ + if ( pSharedInfo->DebugInfo.fPouchCounter == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.PouchCounterFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.PouchCounterFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.PouchCounterFieldOfst.byFieldSize; + + ulResult = Oct6100ApiReadDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + &ulTempData ); + + /* Create the mask to retrieve the appropriate value. */ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + /* Mask data. */ + ulTempData &= ulMask; + /* Move to right position. */ + ulTempData = ulTempData >> ulFeatureBitOffset; + + f_pGetData->pbyData[ ulUserBufWriteIndex + 510 ] = (UINT8)( ( ulTempData >> 8 ) & 0xFF ); + f_pGetData->pbyData[ ulUserBufWriteIndex + 511 ] = (UINT8)( ( ulTempData >> 0 ) & 0xFF ); + } + + /* Add "ISR is not called" bit. */ + if ( pSharedInfo->IntrptManage.fIsrCalled == FALSE ) + { + f_pGetData->pbyData[ ulUserBufWriteIndex + 510 ] |= 0x80; + } + + ulUserBufWriteIndex += 512; + + /* The version has been copied. */ + pSharedInfo->DebugInfo.fImageVersionCopied = TRUE; + } + } + + /* If the image version has been copied, proceed with the API version. */ + if ( pSharedInfo->DebugInfo.fImageVersionCopied == TRUE ) + { + if ( pSharedInfo->DebugInfo.fApiVersionCopied == FALSE ) + { + if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) >= sizeof(cOCT6100_API_VERSION) ) + { + Oct6100UserMemCopy( &f_pGetData->pbyData[ ulUserBufWriteIndex ], cOCT6100_API_VERSION, sizeof(cOCT6100_API_VERSION) ); + ulUserBufWriteIndex += sizeof(cOCT6100_API_VERSION); + + /* The API version has been copied. */ + pSharedInfo->DebugInfo.fApiVersionCopied = TRUE; + } + } + } + } + + /* Check if we are done! */ + if ( pSharedInfo->DebugInfo.fApiVersionCopied == TRUE ) + { + /* Done dumping. */ + + /* Reset data being dumpped flag. */ + pSharedInfo->DebugInfo.fDebugDataBeingDumped = FALSE; + + /* Reset data recording in the chip. */ + WriteBurstParams.ulWriteAddress = pSharedInfo->DebugInfo.ulHotChannelSelectBaseAddress; + WriteBurstParams.ulWriteLength = 2; + WriteBurstParams.pusWriteData = pSharedInfo->DebugInfo.ausHotChannelData; + + mOCT6100_DRIVER_WRITE_BURST_API( WriteBurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + fResetRemainingDataFlag = TRUE; + } + } + } + else /* if ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) */ + { + fResetRemainingDataFlag = TRUE; + } + } + } + + /* Return number of valid bytes in buffer to user. */ + f_pGetData->ulValidNumBytes = ulUserBufWriteIndex; + + /* Update remaining bytes. */ + pSharedInfo->DebugInfo.ulDebugDataRemainingNumBytes -= ulUserBufWriteIndex; + + /* Return remaining bytes. */ + f_pGetData->ulRemainingNumBytes = pSharedInfo->DebugInfo.ulDebugDataRemainingNumBytes; + + /* Return total number of bytes. */ + f_pGetData->ulTotalNumBytes = pSharedInfo->DebugInfo.ulDebugDataTotalNumBytes; + + /* Check if we are done dump the requested content. */ + if ( fResetRemainingDataFlag == TRUE ) + pSharedInfo->DebugInfo.ulDebugDataTotalNumBytes = cOCT6100_INVALID_VALUE; + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_events.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_events.c new file mode 100644 index 0000000..776c6d9 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_events.c @@ -0,0 +1,1379 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_events.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains functions used to retrieve tone and playout events. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 81 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_events_inst.h" +#include "oct6100api/oct6100_tone_detection_inst.h" +#include "oct6100api/oct6100_playout_buf_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_events_pub.h" +#include "oct6100api/oct6100_tone_detection_pub.h" +#include "oct6100api/oct6100_playout_buf_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_events_priv.h" +#include "oct6100_tone_detection_priv.h" +#include "oct6100_playout_buf_priv.h" + +/**************************** PUBLIC FUNCTIONS *****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100EventGetTone + +Description: Retreives an array of tone events. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pEventGetTone Pointer to structure used to store the Tone events. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100EventGetToneDef +UINT32 Oct6100EventGetToneDef( + tPOCT6100_EVENT_GET_TONE f_pEventGetTone ) +{ + f_pEventGetTone->pToneEvent = NULL; + f_pEventGetTone->ulMaxToneEvent = 1; + f_pEventGetTone->ulNumValidToneEvent = cOCT6100_INVALID_VALUE; + f_pEventGetTone->fMoreEvents = FALSE; + f_pEventGetTone->fResetBufs = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100EventGetTone +UINT32 Oct6100EventGetTone( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_EVENT_GET_TONE f_pEventGetTone ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100EventGetToneSer( f_pApiInstance, f_pEventGetTone ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutGetEvent + +Description: Retrieves an array of playout stop events. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pBufPlayoutGetEvent Pointer to structure used to store the playout events. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutGetEventDef +UINT32 Oct6100BufferPlayoutGetEventDef( + tPOCT6100_BUFFER_PLAYOUT_GET_EVENT f_pBufPlayoutGetEvent ) +{ + f_pBufPlayoutGetEvent->pBufferPlayoutEvent = NULL; + f_pBufPlayoutGetEvent->ulMaxEvent = 1; + f_pBufPlayoutGetEvent->ulNumValidEvent = cOCT6100_INVALID_VALUE; + f_pBufPlayoutGetEvent->fMoreEvents = FALSE; + f_pBufPlayoutGetEvent->fResetBufs = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100BufferPlayoutGetEvent +UINT32 Oct6100BufferPlayoutGetEvent( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_BUFFER_PLAYOUT_GET_EVENT f_pBufPlayoutGetEvent ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100BufferPlayoutGetEventSer( f_pApiInstance, f_pBufPlayoutGetEvent ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetEventsSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of the tone events and playout events + software buffers. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pOpenChip Pointer to chip configuration struct. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetEventsSwSizes +UINT32 Oct6100ApiGetEventsSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + + { + UINT32 ulTempVar; + + /* Memory needed by soft tone event buffers. */ + + /* Add 1 to the circular buffer such that all user requested events can fit in the circular queue. */ + f_pInstSizes->ulSoftToneEventsBuffer = ( f_pOpenChip->ulSoftToneEventsBufSize + 1 ) * sizeof( tOCT6100_API_TONE_EVENT ); + + /* Round off the sizes of the soft buffers above. */ + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulSoftToneEventsBuffer, ulTempVar ) + } + + { + UINT32 ulTempVar; + + /* Memory needed by soft playout stop event buffers. */ + if ( f_pOpenChip->ulSoftBufferPlayoutEventsBufSize != cOCT6100_INVALID_VALUE ) + { + f_pInstSizes->ulSoftBufPlayoutEventsBuffer = ( f_pOpenChip->ulSoftBufferPlayoutEventsBufSize + 1 ) * sizeof( tOCT6100_API_BUFFER_PLAYOUT_EVENT ); + + /* Round off the sizes of the soft buffers above. */ + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulSoftBufPlayoutEventsBuffer, ulTempVar ) + } + else /* if ( f_pInstSizes->ulSoftBufferPlayoutEventsBufSize == cOCT6100_INVALID_VALUE ) */ + { + f_pInstSizes->ulSoftBufPlayoutEventsBuffer = 0; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100EventGetToneSer + +Description: Retreives an array of tone event from the software event buffer. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pEventGetTone Pointer to structure which will contain the retreived + events. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100EventGetToneSer +UINT32 Oct6100EventGetToneSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_EVENT_GET_TONE f_pEventGetTone ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_TONE_EVENT pSoftEvent; + UINT32 ulSoftReadPnt; + UINT32 ulSoftWritePnt; + UINT32 ulSoftBufSize; + UINT32 ulNumEventsReturned; + UINT32 ulResult; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the parameters given by the user. */ + if ( f_pEventGetTone->fResetBufs != TRUE && + f_pEventGetTone->fResetBufs != FALSE ) + return cOCT6100_ERR_EVENTS_GET_TONE_RESET_BUFS; + + /* Check max tones. */ + if ( f_pEventGetTone->ulMaxToneEvent > pSharedInfo->ChipConfig.ulSoftToneEventsBufSize ) + return cOCT6100_ERR_EVENTS_MAX_TONES; + + if ( f_pEventGetTone->fResetBufs == FALSE ) + { + /* Check if the events need to be fetched from the chip buffer. */ + ulSoftReadPnt = pSharedInfo->SoftBufs.ulToneEventBufferReadPtr; + ulSoftWritePnt = pSharedInfo->SoftBufs.ulToneEventBufferWritePtr; + + if ( ulSoftReadPnt == ulSoftWritePnt ) + { + ulResult = Oct6100ApiTransferToneEvents( f_pApiInstance, f_pEventGetTone->fResetBufs ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* If there are no events in the soft buffer then there are none in the chip */ + /* either, so return the empty case. Else, return the events in the buffer. */ + ulSoftReadPnt = pSharedInfo->SoftBufs.ulToneEventBufferReadPtr; + ulSoftWritePnt = pSharedInfo->SoftBufs.ulToneEventBufferWritePtr; + ulSoftBufSize = pSharedInfo->SoftBufs.ulToneEventBufferSize; + + if ( ulSoftReadPnt != ulSoftWritePnt ) + { + ulNumEventsReturned = 0; + + while( (ulSoftReadPnt != ulSoftWritePnt) && ( ulNumEventsReturned != f_pEventGetTone->ulMaxToneEvent) ) + { + /* Get a pointer to the first event in the buffer. */ + mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent ) + pSoftEvent += ulSoftReadPnt; + + f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulChannelHndl = pSoftEvent->ulChannelHandle; + f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulUserChanId = pSoftEvent->ulUserChanId; + f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulTimestamp = pSoftEvent->ulTimestamp; + f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulEventType = pSoftEvent->ulEventType; + f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulToneDetected = pSoftEvent->ulToneDetected; + f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulExtToneDetectionPort = pSoftEvent->ulExtToneDetectionPort; + + /* Update the pointers of the soft buffer. */ + ulSoftReadPnt++; + if ( ulSoftReadPnt == ulSoftBufSize ) + ulSoftReadPnt = 0; + + ulNumEventsReturned++; + } + + pSharedInfo->SoftBufs.ulToneEventBufferReadPtr = ulSoftReadPnt; + + /* Detemine if there are more events pending in the soft buffer. */ + if ( ulSoftReadPnt != ulSoftWritePnt ) + f_pEventGetTone->fMoreEvents = TRUE; + else /* ( ulSoftReadPnt == ulSoftWritePnt ) */ + { + f_pEventGetTone->fMoreEvents = FALSE; + + /* Remember this state in the interrupt manager. */ + pSharedInfo->IntrptManage.fToneEventsPending = FALSE; + } + + f_pEventGetTone->ulNumValidToneEvent = ulNumEventsReturned; + } + else + { + /* No valid tone.*/ + f_pEventGetTone->ulNumValidToneEvent = 0; + f_pEventGetTone->fMoreEvents = FALSE; + + /* Remember this state in the interrupt manager. */ + pSharedInfo->IntrptManage.fToneEventsPending = FALSE; + + return cOCT6100_ERR_EVENTS_TONE_BUF_EMPTY; + } + } + else /* ( f_pEventGetTone->fResetBufs == TRUE ) */ + { + /* Empty the hardware buffer. */ + ulResult = Oct6100ApiTransferToneEvents( f_pApiInstance, f_pEventGetTone->fResetBufs ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* If the buffers are to be reset then update the pointers and full flag. */ + pSharedInfo->SoftBufs.ulToneEventBufferReadPtr = 0; + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0; + + f_pEventGetTone->fMoreEvents = FALSE; + f_pEventGetTone->ulNumValidToneEvent = 0; + + /* Remember this state in the interrupt manager. */ + pSharedInfo->IntrptManage.fToneEventsPending = FALSE; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiTransferToneEvents + +Description: Transfers all tone events from the PGSP event out chip buffer + to the soft buffer. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulResetBuf Reset flag. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiTransferToneEvents +UINT32 Oct6100ApiTransferToneEvents( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulResetBuf ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_TONE_EVENT pSoftEvent; + tPOCT6100_API_CHANNEL pEchoChannel; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_READ_BURST_PARAMS BurstParams; + UINT32 ulChipBufFill; + UINT32 ulChipWritePtr = 0; + UINT32 ulChipReadPtr = 0; + + UINT32 usChannelIndex; + UINT32 ulBaseTimestamp; + UINT32 ulToneCnt; + UINT32 ulNumWordsToRead; + UINT32 ulEventCode; + + UINT32 ulResult; + UINT32 i, j; + UINT16 usReadData; + UINT16 ausReadData[ cOCT6100_NUM_WORDS_PER_TONE_EVENT ]; + + UINT32 ulExtToneDetectionPort; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* If the buffer is to be reset then clear the overflow flag. */ + if ( f_ulResetBuf == TRUE ) + { + pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt = 0; + } + + /* Set some parameters of read struct. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Get the current read pointer of the chip buffer. */ + ReadParams.ulReadAddress = cOCT6100_TONE_EVENT_READ_PTR_REG; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulChipReadPtr = usReadData; + + /* Now get the current write pointer. */ + ReadParams.ulReadAddress = cOCT6100_TONE_EVENT_WRITE_PTR_REG; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulChipWritePtr = usReadData; + + ulChipBufFill = (( ulChipWritePtr - ulChipReadPtr ) & ( cOCT6100_NUM_PGSP_EVENT_OUT - 1 )); + + /* Set some parameters of write structs. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Read in the tone event one at a time. */ + for ( i = 0; i < ulChipBufFill; i++ ) + { + /* Skip the event processing if the buffer is to be reset. */ + if ( f_ulResetBuf == TRUE ) + { + /* Update the control variables of the buffer. */ + ulChipReadPtr++; + if ( cOCT6100_NUM_PGSP_EVENT_OUT == ulChipReadPtr ) + ulChipReadPtr = 0; + } + else + { + /* Read in the event only if there's enough room in the soft buffer, and */ + /* the chip buffer is NOT to be reset. */ + if ( ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferReadPtr) && + ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferSize || pSharedInfo->SoftBufs.ulToneEventBufferReadPtr != 0) ) + { + BurstParams.ulReadAddress = cOCT6100_PGSP_EVENT_OUT_BASE + ( ulChipReadPtr * cOCT6100_PGSP_TONE_EVENT_SIZE ); + BurstParams.pusReadData = ausReadData; + + ulNumWordsToRead = cOCT6100_PGSP_TONE_EVENT_SIZE / 2; + + while ( ulNumWordsToRead > 0 ) + { + if ( ulNumWordsToRead > pSharedInfo->ChipConfig.usMaxRwAccesses ) + { + BurstParams.ulReadLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + } + else + { + BurstParams.ulReadLength = ulNumWordsToRead; + } + + mOCT6100_DRIVER_READ_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + BurstParams.pusReadData += BurstParams.ulReadLength; + BurstParams.ulReadAddress += BurstParams.ulReadLength * 2; + + ulNumWordsToRead -= BurstParams.ulReadLength; + } + + /* Verify if the event is valid. */ + if ( ( ausReadData[ 0 ] & cOCT6100_VALID_TONE_EVENT ) == 0x0 ) + return cOCT6100_ERR_FATAL_2D; + + /* First extract the channel number of the tone event. */ + usChannelIndex = ausReadData[ 1 ] & 0x3FF; + + /* Now the timestamp. */ + ulBaseTimestamp = ausReadData[ 2 ] << 16; + ulBaseTimestamp |= ausReadData[ 3 ]; + + /* This timestamp is 256 in adwance, must remove 256 frames. */ + ulBaseTimestamp -= 256; + + /* Fetch the channel stucture to validate which event can be reported. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChannel, usChannelIndex ); + + if ( pEchoChannel->fReserved != TRUE ) + { + /* Update the control variables of the buffer. */ + ulChipReadPtr++; + if ( ulChipReadPtr == cOCT6100_NUM_PGSP_EVENT_OUT ) + ulChipReadPtr = 0; + + /* This channel has been closed since the generation of the event. */ + continue; + } + + /* Extract the extended tone detection port if available. */ + if ( pEchoChannel->ulExtToneChanMode == cOCT6100_API_EXT_TONE_SIN_PORT_MODE ) + { + ulExtToneDetectionPort = cOCT6100_CHANNEL_PORT_SIN; + } + else if ( pEchoChannel->ulExtToneChanMode == cOCT6100_API_EXT_TONE_RIN_PORT_MODE ) + { + ulExtToneDetectionPort = cOCT6100_CHANNEL_PORT_RIN; + + /* Modify the channel index. */ + usChannelIndex = pEchoChannel->usExtToneChanIndex; + + /* Change the channel entry to the original one for statistical purposes. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChannel, usChannelIndex ); + + } + else /* pEchoChannel->ulExtToneChanMode == cOCT6100_API_EXT_TONE_DISABLED */ + { + ulExtToneDetectionPort = cOCT6100_INVALID_VALUE; + } + + ulToneCnt = 0; + /* Verify all the possible events that might have been detected. */ + for ( j = 4; j < cOCT6100_NUM_WORDS_PER_TONE_EVENT; j++ ) + { + ulEventCode = ( ausReadData[ j ] >> 8 ) & 0x7; + + if ( ulEventCode != 0x0 ) + { + /* This tone generated an event, now check if event is masked for the channel. */ + if ((( pEchoChannel->aulToneConf[ ulToneCnt / 32 ] >> ( 31 - ( ulToneCnt % 32 ))) & 0x1) == 1 ) + { + BOOL f2100Tone; + + /* Check if it is a 2100 Tone STOP and if the user wants receive those events*/ + ulResult = Oct6100ApiIs2100Tone(f_pApiInstance, + pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID, + &f2100Tone); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( (f2100Tone == FALSE) || + ( (f2100Tone == TRUE) && (ulEventCode != 2) ) || + ( (f2100Tone == TRUE) && pSharedInfo->ChipConfig.fEnable2100StopEvent == TRUE ) ) + { + + /* If enough space. */ + if ( ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferReadPtr) && + ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferSize || pSharedInfo->SoftBufs.ulToneEventBufferReadPtr != 0) ) + { + /* The tone event is not masked, The API can create a soft tone event. */ + mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent ) + pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr; + + /* Decode the event type. */ + switch( ulEventCode ) + { + case 1: + pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT; + break; + case 2: + pSoftEvent->ulEventType = cOCT6100_TONE_STOP; + break; + case 3: + /* This one is a little tricky. We first */ + /* generate the "PRESENT" event and then generate the "STOP" event. */ + + pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT; + pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | usChannelIndex; + pSoftEvent->ulUserChanId = pEchoChannel->ulUserChanId; + pSoftEvent->ulToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID; + /* We want the timestamp not to be equal to the "STOP" event, so we subtract one to the detector's value. */ + pSoftEvent->ulTimestamp = ( ulBaseTimestamp + ((( ausReadData[ j ] >> 13 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT ) ) - 1; + pSoftEvent->ulExtToneDetectionPort = ulExtToneDetectionPort; + + /* Update the control variables of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr++; + if ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr == pSharedInfo->SoftBufs.ulToneEventBufferSize ) + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0; + + /* If enough space for the "STOP" event. */ + if ( ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferReadPtr) && + ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferSize || pSharedInfo->SoftBufs.ulToneEventBufferReadPtr != 0) ) + { + mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent ) + pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr; + + pSoftEvent->ulEventType = cOCT6100_TONE_STOP; + } + else + { + /* Set the overflow flag of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++; + + /* We continue in the loop in order to empty the hardware buffer. */ + continue; + } + + break; + case 4: + pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT; + break; + default: + pSharedInfo->ErrorStats.ulToneDetectorErrorCnt++; + /* do not process this packet*/ + continue; + } + + pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | usChannelIndex; + pSoftEvent->ulUserChanId = pEchoChannel->ulUserChanId; + pSoftEvent->ulToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID; + pSoftEvent->ulTimestamp = ulBaseTimestamp + ((( ausReadData[ j ] >> 13 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT ); + pSoftEvent->ulExtToneDetectionPort = ulExtToneDetectionPort; + + /* Update the control variables of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr++; + if ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr == pSharedInfo->SoftBufs.ulToneEventBufferSize ) + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0; + + /* Set the interrupt manager such that the user knows that some tone events */ + /* are pending in the software Q. */ + pSharedInfo->IntrptManage.fToneEventsPending = TRUE; + } + else + { + /* Set the overflow flag of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++; + + /* We continue in the loop in order to empty the hardware buffer. */ + } + } + } + else + { + BOOL fSSTone; + + ulResult = Oct6100ApiIsSSTone( + f_pApiInstance, + pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID, + &fSSTone ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( fSSTone == TRUE ) + { + /* Check if this is a "PRESENT" or "STOP" event */ + switch( ulEventCode ) + { + case 1: + /* This is a signaling system present event. Keep this in the instance memory. */ + pEchoChannel->ulLastSSToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID; + pEchoChannel->ulLastSSToneTimestamp = ulBaseTimestamp + ((( ausReadData[ j ] >> 13 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT ); + break; + case 2: + /* This is the "STOP" event, invalidate the last value. The user does not want to know about this. */ + pEchoChannel->ulLastSSToneDetected = (PTR_TYPE)cOCT6100_INVALID_VALUE; + pEchoChannel->ulLastSSToneTimestamp = (PTR_TYPE)cOCT6100_INVALID_VALUE; + break; + default: + break; + } + } + } + } + ulToneCnt++; + + /* Check the other tone of this word. */ + ulEventCode = ausReadData[ j ] & 0x7; + + if ( ulEventCode != 0x0 ) + { + if ((( pEchoChannel->aulToneConf[ ulToneCnt / 32 ] >> ( 31 - ( ulToneCnt % 32 ))) & 0x1) == 1 ) + { + BOOL f2100Tone; + + /* Check if it is a 2100 Tone STOP and if the user wants receive those events*/ + ulResult = Oct6100ApiIs2100Tone(f_pApiInstance, + pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID, + &f2100Tone); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( (f2100Tone == FALSE) || + ( (f2100Tone == TRUE) && (ulEventCode != 2) ) || + ( (f2100Tone == TRUE) && pSharedInfo->ChipConfig.fEnable2100StopEvent == TRUE ) ) + { + + /* If enough space. */ + if ( ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferReadPtr) && + ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferSize || pSharedInfo->SoftBufs.ulToneEventBufferReadPtr != 0) ) + { + /* The tone event is not masked, The API can create a soft tone event. */ + mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent ) + pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr; + + /* Decode the event type. */ + switch( ulEventCode ) + { + case 1: + pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT; + break; + case 2: + pSoftEvent->ulEventType = cOCT6100_TONE_STOP; + break; + case 3: + /* This one is a little tricky. We first */ + /* generate the "PRESENT" event and then generate the "STOP" event. */ + + pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT; + pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | usChannelIndex; + pSoftEvent->ulUserChanId = pEchoChannel->ulUserChanId; + pSoftEvent->ulToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID; + /* We want the timestamp not to be equal to the "STOP" event, so we subtract one to the detector's value. */ + pSoftEvent->ulTimestamp = ( ulBaseTimestamp + ((( ausReadData[ j ] >> 5 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT ) ) - 1; + pSoftEvent->ulExtToneDetectionPort = ulExtToneDetectionPort; + + /* Update the control variables of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr++; + if ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr == pSharedInfo->SoftBufs.ulToneEventBufferSize ) + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0; + + /* If enough space for the "STOP" event. */ + if ( ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferReadPtr) && + ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferSize || pSharedInfo->SoftBufs.ulToneEventBufferReadPtr != 0) ) + { + mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent ) + pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr; + + pSoftEvent->ulEventType = cOCT6100_TONE_STOP; + } + else + { + /* Set the overflow flag of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++; + + /* We continue in the loop in order to empty the hardware buffer. */ + continue; + } + + break; + case 4: + pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT; + break; + default: + pSharedInfo->ErrorStats.ulToneDetectorErrorCnt++; + /* Do not process this packet. */ + continue; + } + + pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | usChannelIndex; + pSoftEvent->ulUserChanId = pEchoChannel->ulUserChanId; + pSoftEvent->ulToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID; + pSoftEvent->ulTimestamp = ulBaseTimestamp + ((( ausReadData[ j ] >> 5 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT ); + pSoftEvent->ulExtToneDetectionPort = ulExtToneDetectionPort; + + /* Update the control variables of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr++; + if ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr == pSharedInfo->SoftBufs.ulToneEventBufferSize ) + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0; + + /* Set the interrupt manager such that the user knows that some tone events */ + /* are pending in the software Q. */ + pSharedInfo->IntrptManage.fToneEventsPending = TRUE; + + } + else + { + /* Set the overflow flag of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++; + + /* We continue in the loop in order to empty the hardware buffer. */ + } + } + } + else + { + BOOL fSSTone; + + ulResult = Oct6100ApiIsSSTone( + f_pApiInstance, + pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID, + &fSSTone ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( fSSTone == TRUE ) + { + /* Check if this is a "PRESENT" event. */ + switch ( ulEventCode ) + { + case 1: + /* This is a signaling system present event. Keep this in the instance memory. */ + pEchoChannel->ulLastSSToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID; + pEchoChannel->ulLastSSToneTimestamp = ulBaseTimestamp + ((( ausReadData[ j ] >> 5 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT ); + break; + case 2: + /* This is the "STOP" event, invalidate the last value. The user does not want to know about this. */ + pEchoChannel->ulLastSSToneDetected = (PTR_TYPE)cOCT6100_INVALID_VALUE; + pEchoChannel->ulLastSSToneTimestamp = (PTR_TYPE)cOCT6100_INVALID_VALUE; + break; + default: + break; + } + } + } + } + ulToneCnt++; + } + } + else + { + /* Set the overflow flag of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++; + + /* We continue in the loop in order to empty the hardware buffer. */ + } + + /* Update the control variables of the buffer. */ + ulChipReadPtr++; + if ( ulChipReadPtr == cOCT6100_NUM_PGSP_EVENT_OUT ) + ulChipReadPtr = 0; + } + } + + /* Write the value of the new Read pointer.*/ + WriteParams.ulWriteAddress = cOCT6100_TONE_EVENT_READ_PTR_REG; + WriteParams.usWriteData = (UINT16)( ulChipReadPtr ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + + return cOCT6100_ERR_OK; +} +#endif + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutGetEventSer + +Description: Retreives an array of buffer playout event from the software + event buffer. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pEventGetPlayoutStop Pointer to structure which will contain the retreived + events. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutGetEventSer +UINT32 Oct6100BufferPlayoutGetEventSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_GET_EVENT f_pBufPlayoutGetEvent ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BUFFER_PLAYOUT_EVENT pSoftEvent; + UINT32 ulSoftReadPnt; + UINT32 ulSoftWritePnt; + UINT32 ulSoftBufSize; + UINT32 ulNumEventsReturned; + UINT32 ulResult; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the parameters past by the user. */ + if ( f_pBufPlayoutGetEvent->fResetBufs != TRUE && + f_pBufPlayoutGetEvent->fResetBufs != FALSE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_RESET; + + /* Check if software buffer has been allocated and thus enabled. */ + if ( pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize == 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_DISABLED; + + /* Checking max playout events. */ + if ( f_pBufPlayoutGetEvent->ulMaxEvent > pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize ) + return cOCT6100_ERR_BUFFER_PLAYOUT_MAX_EVENT; + + if ( f_pBufPlayoutGetEvent->fResetBufs == FALSE ) + { + /* Check if events need to be fetched from the chip. */ + ulSoftReadPnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr; + ulSoftWritePnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr; + + if ( ulSoftReadPnt == ulSoftWritePnt ) + { + ulResult = Oct6100BufferPlayoutTransferEvents( f_pApiInstance, f_pBufPlayoutGetEvent->fResetBufs ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* If there are no events in the soft buffer then there are none in the chip */ + /* either, so return the empty case. Else, return the events in the buffer. */ + ulSoftReadPnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr; + ulSoftWritePnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr; + ulSoftBufSize = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferSize; + + if ( ulSoftReadPnt != ulSoftWritePnt ) + { + ulNumEventsReturned = 0; + + while( (ulSoftReadPnt != ulSoftWritePnt) && ( ulNumEventsReturned != f_pBufPlayoutGetEvent->ulMaxEvent) ) + { + /* Get a pointer to the first event in the buffer. */ + mOCT6100_GET_BUFFER_PLAYOUT_EVENT_BUF_PNT( pSharedInfo, pSoftEvent ) + pSoftEvent += ulSoftReadPnt; + + f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulChannelHndl = pSoftEvent->ulChannelHandle; + f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulUserChanId = pSoftEvent->ulUserChanId; + f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulChannelPort = pSoftEvent->ulChannelPort; + f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulUserEventId = pSoftEvent->ulUserEventId; + f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulEventType = pSoftEvent->ulEventType; + f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulTimestamp = pSoftEvent->ulTimestamp; + + /* Update the pointers of the soft buffer. */ + ulSoftReadPnt++; + if ( ulSoftReadPnt == ulSoftBufSize ) + ulSoftReadPnt = 0; + + ulNumEventsReturned++; + } + + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr = ulSoftReadPnt; + + /* Detemine if there are more events pending in the soft buffer. */ + if ( ulSoftReadPnt != ulSoftWritePnt ) + f_pBufPlayoutGetEvent->fMoreEvents = TRUE; + else /* ( ulSoftReadPnt == ulSoftWritePnt ) */ + { + f_pBufPlayoutGetEvent->fMoreEvents = FALSE; + + /* Remember this state in the interrupt manager. */ + pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = FALSE; + } + + f_pBufPlayoutGetEvent->ulNumValidEvent = ulNumEventsReturned; + } + else /* if ( ulSoftReadPnt == ulSoftWritePnt ) */ + { + /* No valid buffer playout events. */ + f_pBufPlayoutGetEvent->ulNumValidEvent = 0; + f_pBufPlayoutGetEvent->fMoreEvents = FALSE; + + /* Remember this state in the interrupt manager. */ + pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = FALSE; + + return cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_BUF_EMPTY; + } + } + else /* ( f_pEventGetPlayoutStop->fResetBufs == TRUE ) */ + { + /* Check with the hardware first. */ + ulResult = Oct6100BufferPlayoutTransferEvents( f_pApiInstance, f_pBufPlayoutGetEvent->fResetBufs ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* If the buffers are to be reset, then update the pointers and full flag. */ + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr = 0; + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr = 0; + + f_pBufPlayoutGetEvent->fMoreEvents = FALSE; + f_pBufPlayoutGetEvent->ulNumValidEvent = 0; + + /* Remember this state in the interrupt manager. */ + pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = FALSE; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutTransferEvents + +Description: Check all channels that are currently playing a buffer and + generate an event if a buffer has stopped playing. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulResetBuf Reset flag. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutTransferEvents +UINT32 Oct6100BufferPlayoutTransferEvents( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulResetBuf ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pEchoChannel; + + UINT32 ulChannelIndex; + UINT32 ulResult; + UINT32 ulLastBufPlayoutEventBufferOverflowCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* If the buffer is to be reset then clear the overflow flag. */ + if ( f_ulResetBuf == TRUE ) + { + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt = 0; + /* We are done for now. */ + /* No need to check for new events since the user requested to empty the soft buffer. */ + return cOCT6100_ERR_OK; + } + + /* Check if buffer playout has been activated on some ports. */ + if ( pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts == 0 ) + { + /* Buffer playout has not been activated on any channel, */ + /* let's not waste time here. */ + return cOCT6100_ERR_OK; + } + + /* Save the current overflow count. We want to know if an overflow occured to get out of the loop. */ + ulLastBufPlayoutEventBufferOverflowCnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt; + + /* Search through the list of API channel entry for the ones that need playout event checking. */ + for ( ulChannelIndex = 0; ulChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; ulChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChannel, ulChannelIndex ); + + /* Check if buffer playout is active on this channel, using the optimization flag. */ + /* This flag is redundant of other flags used for playout, but will make the above loop */ + /* much faster. This is needed since this function is called very frequently on systems */ + /* which use buffer playout stop events. */ + if ( pEchoChannel->fBufPlayoutActive == TRUE ) + { + /* Read in the event only if there's enough room in the soft buffer. */ + if ( ulLastBufPlayoutEventBufferOverflowCnt == pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt ) + { + /* Check Rout buffer playout first. */ + if ( ( pEchoChannel->fRinBufPlayoutNotifyOnStop == TRUE ) + && ( pEchoChannel->fRinBufPlaying == TRUE ) ) + { + ulResult = Oct6100BufferPlayoutCheckForSpecificEvent( f_pApiInstance, ulChannelIndex, cOCT6100_CHANNEL_PORT_ROUT, TRUE, NULL ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else /* if ( ulLastBufPlayoutEventBufferOverflowCnt != pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt ) */ + { + /* Get out of the loop, no more events can be inserted in the soft buffer. */ + break; + } + + /* An overflow might have been detected in the lower level function. */ + /* Check the overflow count once again to make sure there might be room for a next event. */ + if ( ulLastBufPlayoutEventBufferOverflowCnt == pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt ) + { + /* Check Sout buffer playout. */ + if ( ( pEchoChannel->fSoutBufPlayoutNotifyOnStop == TRUE ) + && ( pEchoChannel->fSoutBufPlaying == TRUE ) ) + { + ulResult = Oct6100BufferPlayoutCheckForSpecificEvent( f_pApiInstance, ulChannelIndex, cOCT6100_CHANNEL_PORT_SOUT, TRUE, NULL ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else /* if ( ulLastBufPlayoutEventBufferOverflowCnt != pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt ) */ + { + /* Get out of the loop, no more events can be inserted in the soft buffer. */ + break; + } + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutCheckForSpecificEvent + +Description: Check a specific channel/port for playout buffer events. + If asked to, save this event to the software event buffer. + Return a flag specifying whether the event was detected or not. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulChannelIndex Index of the channel to be checked. +f_ulChannelPort Port of the channel to be checked. +f_fSaveToSoftBuffer Save event to software buffer. +f_pfEventDetected Whether or not an event was detected. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutCheckForSpecificEvent +UINT32 Oct6100BufferPlayoutCheckForSpecificEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulChannelPort, + IN BOOL f_fSaveToSoftBuffer, + OUT PBOOL f_pfEventDetected ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BUFFER_PLAYOUT_EVENT pSoftEvent; + tPOCT6100_API_CHANNEL pEchoChannel; + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_GET_TIME GetTimeParms; + + UINT32 ulResult; + UINT16 usReadData; + UINT32 ulReadPtrBytesOfst; + UINT32 ulReadPtrBitOfst; + UINT32 ulReadPtrFieldSize; + + UINT32 ulWritePtrBytesOfst; + UINT32 ulWritePtrBitOfst; + UINT32 ulWritePtrFieldSize; + + UINT32 ulPlayoutBaseAddress; + UINT32 ulTempData; + UINT32 ulReadPtr; + UINT32 ulMask; + UINT32 ulWritePtr; + UINT32 ulUserEventId; + UINT32 ulEventType; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Compare the read and write pointers for matching. If they matched, playout stopped. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChannel, f_ulChannelIndex ); + + /* Set the playout feature base address. */ + ulPlayoutBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_ulChannelIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + + if ( f_ulChannelPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + /* Check on the Rout port. */ + ulUserEventId = pEchoChannel->ulRinUserBufPlayoutEventId; + ulEventType = pEchoChannel->byRinPlayoutStopEventType; + + ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.usDwordOffset * 4; + ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byBitOffset; + ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byFieldSize; + + ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.usDwordOffset * 4; + ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byBitOffset; + ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byFieldSize; + } + else /* if ( f_ulChannelPort == cOCT6100_CHANNEL_PORT_SOUT ) */ + { + /* Check on the Sout port. */ + ulUserEventId = pEchoChannel->ulSoutUserBufPlayoutEventId; + ulEventType = pEchoChannel->bySoutPlayoutStopEventType; + + ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.usDwordOffset * 4; + ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byBitOffset; + ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byFieldSize; + + ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.usDwordOffset * 4; + ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byBitOffset; + ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byFieldSize; + } + + /* Retrieve the current write pointer. */ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulPlayoutBaseAddress + ulWritePtrBytesOfst, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulWritePtrFieldSize, ulWritePtrBitOfst, &ulMask ); + + /* Store the write pointer.*/ + ulWritePtr = ( ulTempData & ulMask ) >> ulWritePtrBitOfst; + + /* Read the read pointer.*/ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + ReadParams.ulReadAddress = ulPlayoutBaseAddress + ulReadPtrBytesOfst; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulReadPtrBitOfst < 16 ) + ReadParams.ulReadAddress += 2; + + /* Must read in memory directly since this value is changed by hardware */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulReadPtrBitOfst < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + mOCT6100_CREATE_FEATURE_MASK( ulReadPtrFieldSize, ulReadPtrBitOfst, &ulMask ); + + /* Store the read pointer. */ + ulReadPtr = ( ulTempData & ulMask ) >> ulReadPtrBitOfst; + + /* Playout has finished when the read pointer reaches the write pointer. */ + if ( ulReadPtr != ulWritePtr ) + { + /* Still playing -- do not generate an event. */ + if ( f_pfEventDetected != NULL ) + *f_pfEventDetected = FALSE; + } + else + { + /* Buffer stopped playing, generate an event here, if asked. */ + if ( ( f_fSaveToSoftBuffer == TRUE ) + && ( ( pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr + 1 ) != pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr ) + && ( ( pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr + 1 ) != pSharedInfo->SoftBufs.ulBufPlayoutEventBufferSize || pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr != 0 ) ) + { + /* The API can create a soft buffer playout event. */ + mOCT6100_GET_BUFFER_PLAYOUT_EVENT_BUF_PNT( pSharedInfo, pSoftEvent ) + pSoftEvent += pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr; + + pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_ulChannelIndex; + pSoftEvent->ulUserChanId = pEchoChannel->ulUserChanId; + pSoftEvent->ulUserEventId = ulUserEventId; + pSoftEvent->ulChannelPort = f_ulChannelPort; + /* For now, only this type of event is available. */ + pSoftEvent->ulEventType = ulEventType; + + /* Generate millisecond timestamp. */ + GetTimeParms.pProcessContext = f_pApiInstance->pProcessContext; + ulResult = Oct6100UserGetTime( &GetTimeParms ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + pSoftEvent->ulTimestamp = ( GetTimeParms.aulWallTimeUs[ 0 ] / 1000 ); + pSoftEvent->ulTimestamp += ( GetTimeParms.aulWallTimeUs[ 1 ] ) * ( 0xFFFFFFFF / 1000 ); + + /* Update the control variables of the buffer. */ + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr++; + if ( pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr == pSharedInfo->SoftBufs.ulBufPlayoutEventBufferSize ) + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr = 0; + + /* Set the interrupt manager such that the user knows that some playout events */ + /* are pending in the software Q. */ + pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = TRUE; + } + else if ( f_fSaveToSoftBuffer == TRUE ) + { + /* Set the overflow flag of the buffer. */ + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt++; + } + + /* Update the channel entry to set the playing flag to FALSE. */ + + /* Select the port of interest. */ + if ( f_ulChannelPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + /* Decrement the number of active buffer playout ports. */ + /* No need to check anything here, it's been done in the calling function. */ + pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts--; + + pEchoChannel->fRinBufPlaying = FALSE; + pEchoChannel->fRinBufPlayoutNotifyOnStop = FALSE; + + /* Clear optimization flag if possible. */ + if ( ( pEchoChannel->fSoutBufPlaying == FALSE ) + && ( pEchoChannel->fSoutBufPlayoutNotifyOnStop == FALSE ) ) + { + /* Buffer playout is no more active on this channel. */ + pEchoChannel->fBufPlayoutActive = FALSE; + } + } + else /* f_ulChannelPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + /* Decrement the number of active buffer playout ports. */ + /* No need to check anything here, it's been done in the calling function. */ + pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts--; + + pEchoChannel->fSoutBufPlaying = FALSE; + pEchoChannel->fSoutBufPlayoutNotifyOnStop = FALSE; + + /* Clear optimization flag if possible. */ + if ( ( pEchoChannel->fRinBufPlaying == FALSE ) + && ( pEchoChannel->fRinBufPlayoutNotifyOnStop == FALSE ) ) + { + /* Buffer playout is no more active on this channel. */ + pEchoChannel->fBufPlayoutActive = FALSE; + } + } + + /* Return that an event was detected. */ + if ( f_pfEventDetected != NULL ) + *f_pfEventDetected = TRUE; + } + + return cOCT6100_ERR_OK; +} +#endif + + diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_interrupts.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_interrupts.c new file mode 100644 index 0000000..898267d --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_interrupts.c @@ -0,0 +1,1997 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_interrupts.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the API's interrupt service routine and all of its + sub-functions. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 81 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_events_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_channel_inst.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_events_priv.h" +#include "oct6100_interrupts_priv.h" + +/**************************** PUBLIC FUNCTIONS *****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100InterruptConfigure + +Description: Configure the operation of all possible interrupt sources. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pIntrptConfig Pointer to interrupt configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100InterruptConfigureDef +UINT32 Oct6100InterruptConfigureDef( + tPOCT6100_INTERRUPT_CONFIGURE f_pIntrptConfig ) +{ + f_pIntrptConfig->ulFatalGeneralConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pIntrptConfig->ulFatalMemoryConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + + f_pIntrptConfig->ulErrorMemoryConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pIntrptConfig->ulErrorOverflowToneEventsConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pIntrptConfig->ulErrorH100Config = cOCT6100_INTERRUPT_NO_TIMEOUT; + + f_pIntrptConfig->ulFatalMemoryTimeout = 100; + + f_pIntrptConfig->ulErrorMemoryTimeout = 100; + f_pIntrptConfig->ulErrorOverflowToneEventsTimeout = 100; + f_pIntrptConfig->ulErrorH100Timeout = 100; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100InterruptConfigure +UINT32 Oct6100InterruptConfigure( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_INTERRUPT_CONFIGURE f_pIntrptConfig ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulResult; + UINT32 ulFncRes; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Create serialization object for ISR. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulResult = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Call serialized sub-function. */ + ulFncRes = Oct6100InterruptConfigureSer( f_pApiInstance, f_pIntrptConfig, TRUE ); + /* Release serialization object. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulResult = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if an error occured in sub-function. */ + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100InterruptServiceRoutine + +Description: The API's interrupt service routine. This function clears all + register ROLs which have generated an interrupt and report the + events in the user supplied structure. Also, the tone event + and/or playout event buffer will be emptied if valid events + are present. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pIntFlags Pointer to structure containing event flags returned + to user. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100InterruptServiceRoutineDef +UINT32 Oct6100InterruptServiceRoutineDef( + tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ) +{ + f_pIntFlags->fFatalGeneral = FALSE; + f_pIntFlags->ulFatalGeneralFlags = 0x0; + f_pIntFlags->fFatalReadTimeout = FALSE; + + f_pIntFlags->fErrorRefreshTooLate = FALSE; + f_pIntFlags->fErrorPllJitter = FALSE; + + f_pIntFlags->fErrorOverflowToneEvents = FALSE; + + f_pIntFlags->fErrorH100OutOfSync = FALSE; + f_pIntFlags->fErrorH100ClkA = FALSE; + f_pIntFlags->fErrorH100ClkB = FALSE; + f_pIntFlags->fErrorH100FrameA = FALSE; + + f_pIntFlags->fToneEventsPending = FALSE; + f_pIntFlags->fBufferPlayoutEventsPending = FALSE; + + f_pIntFlags->fApiSynch = FALSE; + + + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100InterruptServiceRoutine +UINT32 Oct6100InterruptServiceRoutine( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulResult; + UINT32 ulFncRes; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize the serialization object for the ISR. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulResult = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Call the serialized sub-function. */ + ulFncRes = Oct6100InterruptServiceRoutineSer( f_pApiInstance, f_pIntFlags ); + } + else + { + return ulResult; + } + + /* Release the serialization object. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulResult = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check for an error in the sub-function. */ + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiIsrSwInit + +Description: Initializes portions of API instance associated to the API's + interrupt service routine. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiIsrSwInit +UINT32 Oct6100ApiIsrSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the state of each interrupt group to disabled. The state will */ + /* be updated to the true configuration once the configure interrupts function is called. */ + pSharedInfo->IntrptManage.byFatalGeneralState = cOCT6100_INTRPT_DISABLED; + pSharedInfo->IntrptManage.byFatalMemoryState = cOCT6100_INTRPT_DISABLED; + pSharedInfo->IntrptManage.byErrorMemoryState = cOCT6100_INTRPT_DISABLED; + pSharedInfo->IntrptManage.byErrorH100State = cOCT6100_INTRPT_DISABLED; + pSharedInfo->IntrptManage.byErrorOverflowToneEventsState = cOCT6100_INTRPT_DISABLED; + + /* Indicate that the mclk interrupt is not active at the moment. */ + pSharedInfo->IntrptManage.fMclkIntrptActive = FALSE; + + /* Indicate that no buffer playout events are pending for the moment. */ + pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = FALSE; + + /* Indicate that no tone events are pending for the moment. */ + pSharedInfo->IntrptManage.fToneEventsPending = FALSE; + + /* The ISR has never been called. */ + pSharedInfo->IntrptManage.fIsrCalled = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiIsrHwInit + +Description: Initializes the chip's interrupt registers. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pIntrptConfig Pointer to structure defining how the interrupts + should be configured. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiIsrHwInit +UINT32 Oct6100ApiIsrHwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_INTERRUPT_CONFIGURE f_pIntrptConfig ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Set some parameters of write struct. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /*==================================================================================*/ + /* Enable all the interrupts */ + + WriteParams.ulWriteAddress = 0x104; + WriteParams.usWriteData = 0x0001; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x204; + WriteParams.usWriteData = 0x1C05; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x304; + WriteParams.usWriteData = 0xFFFF; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x504; + WriteParams.usWriteData = 0x0002; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x704; + WriteParams.usWriteData = 0x0007; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==================================================================================*/ + + /* Calculate the number of mclk cycles in 1 ms. */ + f_pApiInstance->pSharedInfo->IntrptManage.ulNumMclkCyclesIn1Ms = f_pApiInstance->pSharedInfo->MiscVars.ulMclkFreq / 1000; + + /* Configure the interrupt registers as requested by the user. */ + ulResult = Oct6100InterruptConfigureSer( f_pApiInstance, f_pIntrptConfig, TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100InterruptConfigureSer + +Description: Configure the operation of interrupt groups. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pIntrptConfig Pointer to interrupt configuration structure. +f_fCheckParams Check parameter enable flag. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100InterruptConfigureSer +UINT32 Oct6100InterruptConfigureSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_INTERRUPT_CONFIGURE f_pIntrptConfig, + IN BOOL f_fCheckParams ) +{ + tPOCT6100_API_INTRPT_CONFIG pIntrptConfig; + tPOCT6100_API_INTRPT_MANAGE pIntrptManage; + UINT32 ulResult; + + /* Check for errors. */ + if ( f_fCheckParams == TRUE ) + { + if ( f_pIntrptConfig->ulFatalGeneralConfig != cOCT6100_INTERRUPT_DISABLE && + f_pIntrptConfig->ulFatalGeneralConfig != cOCT6100_INTERRUPT_NO_TIMEOUT ) + return cOCT6100_ERR_INTRPTS_FATAL_GENERAL_CONFIG; + if ( f_pIntrptConfig->ulFatalMemoryConfig != cOCT6100_INTERRUPT_DISABLE && + f_pIntrptConfig->ulFatalMemoryConfig != cOCT6100_INTERRUPT_TIMEOUT && + f_pIntrptConfig->ulFatalMemoryConfig != cOCT6100_INTERRUPT_NO_TIMEOUT ) + return cOCT6100_ERR_INTRPTS_FATAL_MEMORY_CONFIG; + if ( f_pIntrptConfig->ulErrorMemoryConfig != cOCT6100_INTERRUPT_DISABLE && + f_pIntrptConfig->ulErrorMemoryConfig != cOCT6100_INTERRUPT_TIMEOUT && + f_pIntrptConfig->ulErrorMemoryConfig != cOCT6100_INTERRUPT_NO_TIMEOUT ) + return cOCT6100_ERR_INTRPTS_DATA_ERR_MEMORY_CONFIG; + if ( f_pIntrptConfig->ulErrorOverflowToneEventsConfig != cOCT6100_INTERRUPT_DISABLE && + f_pIntrptConfig->ulErrorOverflowToneEventsConfig != cOCT6100_INTERRUPT_TIMEOUT && + f_pIntrptConfig->ulErrorOverflowToneEventsConfig != cOCT6100_INTERRUPT_NO_TIMEOUT ) + return cOCT6100_ERR_INTRPTS_OVERFLOW_TONE_EVENTS_CONFIG; + if ( f_pIntrptConfig->ulErrorH100Config != cOCT6100_INTERRUPT_DISABLE && + f_pIntrptConfig->ulErrorH100Config != cOCT6100_INTERRUPT_TIMEOUT && + f_pIntrptConfig->ulErrorH100Config != cOCT6100_INTERRUPT_NO_TIMEOUT ) + return cOCT6100_ERR_INTRPTS_H100_ERROR_CONFIG; + + if ( f_pIntrptConfig->ulFatalMemoryTimeout < 10 || + f_pIntrptConfig->ulFatalMemoryTimeout > 10000 ) + return cOCT6100_ERR_INTRPTS_FATAL_MEMORY_TIMEOUT; + if ( f_pIntrptConfig->ulErrorMemoryTimeout < 10 || + f_pIntrptConfig->ulErrorMemoryTimeout > 10000 ) + return cOCT6100_ERR_INTRPTS_DATA_ERR_MEMORY_TIMEOUT; + if ( f_pIntrptConfig->ulErrorOverflowToneEventsTimeout < 10 || + f_pIntrptConfig->ulErrorOverflowToneEventsTimeout > 10000 ) + return cOCT6100_ERR_INTRPTS_OVERFLOW_TONE_EVENTS_TIMEOUT; + if ( f_pIntrptConfig->ulErrorH100Timeout < 10 || + f_pIntrptConfig->ulErrorH100Timeout > 10000 ) + return cOCT6100_ERR_INTRPTS_H100_ERROR_TIMEOUT; + } + + /* Copy the configuration to the API instance. */ + pIntrptConfig = &f_pApiInstance->pSharedInfo->IntrptConfig; + pIntrptManage = &f_pApiInstance->pSharedInfo->IntrptManage; + + pIntrptConfig->byFatalGeneralConfig = (UINT8)( f_pIntrptConfig->ulFatalGeneralConfig & 0xFF ); + pIntrptConfig->byFatalMemoryConfig = (UINT8)( f_pIntrptConfig->ulFatalMemoryConfig & 0xFF ); + pIntrptConfig->byErrorMemoryConfig = (UINT8)( f_pIntrptConfig->ulErrorMemoryConfig & 0xFF ); + pIntrptConfig->byErrorOverflowToneEventsConfig = (UINT8)( f_pIntrptConfig->ulErrorOverflowToneEventsConfig & 0xFF ); + pIntrptConfig->byErrorH100Config = (UINT8)( f_pIntrptConfig->ulErrorH100Config & 0xFF ); + + f_pIntrptConfig->ulFatalMemoryTimeout = ((f_pIntrptConfig->ulFatalMemoryTimeout + 9) / 10) * 10; + pIntrptConfig->ulFatalMemoryTimeoutMclk = f_pIntrptConfig->ulFatalMemoryTimeout * pIntrptManage->ulNumMclkCyclesIn1Ms; + + f_pIntrptConfig->ulErrorMemoryTimeout = ((f_pIntrptConfig->ulErrorMemoryTimeout + 9) / 10) * 10; + pIntrptConfig->ulErrorMemoryTimeoutMclk = f_pIntrptConfig->ulErrorMemoryTimeout * pIntrptManage->ulNumMclkCyclesIn1Ms; + + f_pIntrptConfig->ulErrorOverflowToneEventsTimeout = ((f_pIntrptConfig->ulErrorOverflowToneEventsTimeout + 9) / 10) * 10; + pIntrptConfig->ulErrorOverflowToneEventsTimeoutMclk = f_pIntrptConfig->ulErrorOverflowToneEventsTimeout * pIntrptManage->ulNumMclkCyclesIn1Ms; + + f_pIntrptConfig->ulErrorH100Timeout = ((f_pIntrptConfig->ulErrorH100Timeout + 9) / 10) * 10; + pIntrptConfig->ulErrorH100TimeoutMclk = f_pIntrptConfig->ulErrorH100Timeout * pIntrptManage->ulNumMclkCyclesIn1Ms; + + + /*Clear all interrupts that were already enabled*/ + ulResult = Oct6100ApiClearEnabledInterrupts( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Before writing the new configuration to the chip's registers, make sure that any */ + /* interrupts which are either disabled or have no timeout period are not on the */ + /* disabled interrupt list. */ + + /*==================================================================================*/ + if ( pIntrptConfig->byFatalGeneralConfig == cOCT6100_INTERRUPT_DISABLE ) + pIntrptManage->byFatalGeneralState = cOCT6100_INTRPT_DISABLED; + else /* pIntrptConfig->byFatalGeneralConfig == cOCT6100_INTERRUPT_NO_TIMEOUT */ + pIntrptManage->byFatalGeneralState = cOCT6100_INTRPT_ACTIVE; + + /*==================================================================================*/ + if ( pIntrptConfig->byFatalMemoryConfig == cOCT6100_INTERRUPT_DISABLE ) + pIntrptManage->byFatalMemoryState = cOCT6100_INTRPT_DISABLED; + else if ( pIntrptConfig->byFatalMemoryConfig == cOCT6100_INTERRUPT_NO_TIMEOUT ) + pIntrptManage->byFatalMemoryState = cOCT6100_INTRPT_ACTIVE; + else /* ( pIntrptConfig->byFatalMemoryConfig == cOCT6100_INTERRUPT_TIMEOUT ) */ + { + if ( pIntrptManage->byFatalMemoryState == cOCT6100_INTRPT_DISABLED ) + pIntrptManage->byFatalMemoryState = cOCT6100_INTRPT_ACTIVE; + } + + /*==================================================================================*/ + if ( pIntrptConfig->byErrorMemoryConfig == cOCT6100_INTERRUPT_DISABLE ) + pIntrptManage->byErrorMemoryState = cOCT6100_INTRPT_DISABLED; + else if ( pIntrptConfig->byErrorMemoryConfig == cOCT6100_INTERRUPT_NO_TIMEOUT ) + pIntrptManage->byErrorMemoryState = cOCT6100_INTRPT_ACTIVE; + else /* (pIntrptConfig->byErrorMemoryConfig == cOCT6100_INTERRUPT_TIMEOUT ) */ + { + if ( pIntrptManage->byErrorMemoryState == cOCT6100_INTRPT_DISABLED ) + pIntrptManage->byErrorMemoryState = cOCT6100_INTRPT_ACTIVE; + } + + /*==================================================================================*/ + if ( pIntrptConfig->byErrorOverflowToneEventsConfig == cOCT6100_INTERRUPT_DISABLE ) + pIntrptManage->byErrorOverflowToneEventsState = cOCT6100_INTRPT_DISABLED; + else if ( pIntrptConfig->byErrorOverflowToneEventsConfig == cOCT6100_INTERRUPT_NO_TIMEOUT ) + pIntrptManage->byErrorOverflowToneEventsState = cOCT6100_INTRPT_ACTIVE; + else /* (pIntrptConfig->byErrorOverflowToneEventsConfig == cOCT6100_INTERRUPT_TIMEOUT ) */ + { + if ( pIntrptManage->byErrorOverflowToneEventsState == cOCT6100_INTRPT_DISABLED ) + pIntrptManage->byErrorOverflowToneEventsState = cOCT6100_INTRPT_ACTIVE; + } + + /*==================================================================================*/ + if ( pIntrptConfig->byErrorH100Config == cOCT6100_INTERRUPT_DISABLE ) + pIntrptManage->byErrorH100State = cOCT6100_INTRPT_DISABLED; + else if ( pIntrptConfig->byErrorH100Config == cOCT6100_INTERRUPT_NO_TIMEOUT ) + pIntrptManage->byErrorH100State = cOCT6100_INTRPT_ACTIVE; + else /* (pIntrptConfig->byErrorH100Config == cOCT6100_INTERRUPT_TIMEOUT ) */ + { + if ( pIntrptManage->byErrorH100State == cOCT6100_INTRPT_DISABLED ) + pIntrptManage->byErrorH100State = cOCT6100_INTRPT_ACTIVE; + } + + + /* Write to the interrupt registers to update the state of each interrupt group. */ + ulResult = Oct6100ApiWriteIeRegs( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiClearEnabledInterrupts + +Description: Disabled interruption are not reported but still available. This + function will clear the interrupts that were disabled and wish + to enable now. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pIntrptConfig Pointer to interrupt configuration structure. +f_pIntrptManage Pointer to interrupt manager structure. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#if !SKIP_Oct6100ApiClearEnabledInterrupts +UINT32 Oct6100ApiClearEnabledInterrupts( + IN tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tPOCT6100_API_INTRPT_CONFIG pIntrptConfig; + tPOCT6100_API_INTRPT_MANAGE pIntrptManage; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Copy the configuration to the API instance. */ + pIntrptConfig = &f_pApiInstance->pSharedInfo->IntrptConfig; + pIntrptManage = &f_pApiInstance->pSharedInfo->IntrptManage; + + if ( pIntrptConfig->byFatalGeneralConfig != cOCT6100_INTERRUPT_DISABLE && + pIntrptManage->byFatalGeneralState != cOCT6100_INTRPT_DISABLED ) + { + WriteParams.ulWriteAddress = 0x102; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_102H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x202; + WriteParams.usWriteData = 0x1800; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x502; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_502H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pIntrptConfig->byErrorMemoryConfig != cOCT6100_INTERRUPT_DISABLE && + pIntrptManage->byErrorMemoryState != cOCT6100_INTRPT_DISABLED ) + { + WriteParams.ulWriteAddress = 0x202; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_202H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pIntrptConfig->byErrorH100Config != cOCT6100_INTERRUPT_DISABLE && + pIntrptManage->byErrorH100State != cOCT6100_INTRPT_DISABLED ) + { + WriteParams.ulWriteAddress = 0x302; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_302H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pIntrptConfig->byErrorOverflowToneEventsConfig != cOCT6100_INTERRUPT_DISABLE && + pIntrptManage->byErrorOverflowToneEventsState != cOCT6100_INTRPT_DISABLED ) + { + WriteParams.ulWriteAddress = 0x702; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_702H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + + return cOCT6100_ERR_OK; + +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100InterruptServiceRoutineSer + +Description: Serialized sub-function of API's interrupt service routine. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pIntFlags Pointer to structure containing event flags returned + to user. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100InterruptServiceRoutineSer +UINT32 Oct6100InterruptServiceRoutineSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulRegister210h; + UINT32 ulResult; + UINT16 usReadData; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Must update the statistics. Set parameters in read and write structs. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Set all the flags to default values to make sure the variables are initialized. */ + f_pIntFlags->fFatalGeneral = FALSE; + f_pIntFlags->ulFatalGeneralFlags = 0x0; + f_pIntFlags->fFatalReadTimeout = FALSE; + + f_pIntFlags->fErrorRefreshTooLate = FALSE; + f_pIntFlags->fErrorPllJitter = FALSE; + + f_pIntFlags->fErrorH100OutOfSync = FALSE; + f_pIntFlags->fErrorH100ClkA = FALSE; + f_pIntFlags->fErrorH100ClkB = FALSE; + f_pIntFlags->fErrorH100FrameA = FALSE; + f_pIntFlags->fApiSynch = FALSE; + + f_pIntFlags->fErrorOverflowToneEvents = FALSE; + + /* Start by reading registers 210h to determine if any modules have flagged an interrupt. */ + ReadParams.ulReadAddress = 0x210; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + ulRegister210h = usReadData; + + /* Update the extended mclk counter. */ + ulResult = Oct6100ApiReadChipMclkTime( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* If the mclk interrupt is active then check which interrupt timeout periods have expired. */ + ReadParams.ulReadAddress = 0x302; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + if ( (usReadData & 0x1) != 0 && pSharedInfo->IntrptManage.fMclkIntrptActive == TRUE ) + { + /* Update timeout periods. */ + ulResult = Oct6100ApiUpdateIntrptTimeouts( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + f_pIntFlags->fApiSynch = TRUE; + + /* Read registers 210h and 212h again to determine if any modules have flagged an interrupt. */ + ReadParams.ulReadAddress = 0x210; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + ulRegister210h = usReadData; + } + + /* Read the interrupt registers to determine what interrupt conditions have occured. */ + ulResult = Oct6100ApiReadIntrptRegs( f_pApiInstance, f_pIntFlags, ulRegister210h ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Empty the tone buffer if any events are pending. */ + ulResult = Oct6100ApiTransferToneEvents( f_pApiInstance, FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the tone events pending flag. */ + f_pIntFlags->fToneEventsPending = pSharedInfo->IntrptManage.fToneEventsPending; + + /* Check for buffer playout events and insert in the software queue -- if activated. */ + if ( pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize != 0 ) + { + ulResult = Oct6100BufferPlayoutTransferEvents( f_pApiInstance, FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the buffer playout events pending flag. */ + f_pIntFlags->fBufferPlayoutEventsPending = pSharedInfo->IntrptManage.fBufferPlayoutEventsPending; + } + else + { + f_pIntFlags->fBufferPlayoutEventsPending = FALSE; + } + + /* Update the states of each interrupt group. */ + ulResult = Oct6100ApiUpdateIntrptStates( f_pApiInstance, f_pIntFlags ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check the state of the NLP timestamp if required.*/ + ulResult = Oct6100ApiCheckProcessorState( f_pApiInstance, f_pIntFlags ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write to the necessary IE registers. */ + ulResult = Oct6100ApiWriteIntrptRegs( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Schedule the next mclk interrupt, if one is needed. */ + ulResult = Oct6100ApiScheduleNextMclkIntrptSer( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Free the interrupt pin of the chip (i.e. remove minimum time requirement between interrupts). */ + WriteParams.ulWriteAddress = 0x214; + WriteParams.usWriteData = 0x0000; + if ( pSharedInfo->ChipConfig.byInterruptPolarity == cOCT6100_ACTIVE_HIGH_POLARITY ) + WriteParams.usWriteData |= 0x4000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Indicate that the interrupt ROLs have been treated. */ + WriteParams.ulWriteAddress = 0x212; + WriteParams.usWriteData = 0x8000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReadIntrptRegs + +Description: Reads the interrupt registers of all modules currently + indicating an interrupt condition. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pIntFlags Pointer to an interrupt flag structure. +f_ulRegister210h Value of register 0x210. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReadIntrptRegs +UINT32 Oct6100ApiReadIntrptRegs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT tPOCT6100_INTERRUPT_FLAGS f_pIntFlags, + IN UINT32 f_ulRegister210h ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_ERROR_STATS pErrorStats; + tPOCT6100_API_INTRPT_MANAGE pIntrptManage; + tOCT6100_READ_PARAMS ReadParams; + + UINT32 ulResult; + UINT16 usReadData; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulTempData; + UINT32 ulCounterValue; + UINT32 ulMask; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + pErrorStats = &pSharedInfo->ErrorStats; + pIntrptManage = &pSharedInfo->IntrptManage; + + /* Set some parameters of read struct. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* CPU registers. */ + if ( (f_ulRegister210h & 0x00001) != 0 ) + { + /*=======================================================================*/ + /* Read registers of this module. */ + ReadParams.ulReadAddress = 0x102; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check which interrupt(s) were set. */ + if ( (usReadData & 0x0001) != 0 ) + { + f_pIntFlags->fFatalReadTimeout = TRUE; + pErrorStats->ulInternalReadTimeoutCnt++; + } + + pIntrptManage->usRegister102h = usReadData; + /*=======================================================================*/ + } + else + { + pIntrptManage->usRegister102h = 0x0; + } + + /* MAIN registers. */ + if ( (f_ulRegister210h & 0x00002) != 0 ) + { + /*=======================================================================*/ + /* Read registers of this module. */ + ReadParams.ulReadAddress = 0x202; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save current value in instance. */ + pIntrptManage->usRegister202h = usReadData; + + /* Check which interrupts were set. */ + if ( (usReadData & 0x0001) != 0 ) + { + f_pIntFlags->fErrorRefreshTooLate = TRUE; + pErrorStats->ulSdramRefreshTooLateCnt++; + } + if ( (usReadData & 0x0800) != 0 ) + { + f_pIntFlags->ulFatalGeneralFlags |= cOCT6100_FATAL_GENERAL_ERROR_TYPE_1; + f_pIntFlags->fFatalGeneral = TRUE; + pErrorStats->fFatalChipError = TRUE; + } + if ( (usReadData & 0x1000) != 0 ) + { + f_pIntFlags->ulFatalGeneralFlags |= cOCT6100_FATAL_GENERAL_ERROR_TYPE_2; + f_pIntFlags->fFatalGeneral = TRUE; + pErrorStats->fFatalChipError = TRUE; + } + if ( (usReadData & 0x0400) != 0 ) + { + f_pIntFlags->fErrorPllJitter = TRUE; + pErrorStats->ulPllJitterErrorCnt++; + + /* Update the PLL jitter error count here. */ + if ( pSharedInfo->DebugInfo.fPouchCounter == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.PouchCounterFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.PouchCounterFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.PouchCounterFieldOfst.byFieldSize; + + ulResult = Oct6100ApiReadDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + &ulTempData ); + + /* Read previous value set in the feature field. */ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + /* Update counter. */ + ulCounterValue = ulTempData & ulMask; + ulCounterValue = ulCounterValue >> ulFeatureBitOffset; + ulCounterValue ++; + /* Handle wrap around case. */ + ulCounterValue &= ( 1 << ulFeatureFieldLength ) - 1; + + /* Clear old counter value. */ + ulTempData &= (~ulMask); + ulTempData |= ulCounterValue << ulFeatureBitOffset; + + /* Write the DWORD where the field is located.*/ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /*=======================================================================*/ + } + else + { + pIntrptManage->usRegister202h = 0x0; + } + + /* H.100 registers. */ + if ( (f_ulRegister210h & 0x00004) != 0 ) + { + /*=======================================================================*/ + /* Read registers of this module. */ + ReadParams.ulReadAddress = 0x302; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check which interrupts were set. */ + if ( (usReadData & 0x0100) != 0 ) + { + f_pIntFlags->fErrorH100OutOfSync = TRUE; + pErrorStats->ulH100OutOfSyncCnt++; + } + if ( (usReadData & 0x1000) != 0 ) + { + f_pIntFlags->fErrorH100FrameA = TRUE; + pErrorStats->ulH100FrameABadCnt++; + } + if ( (usReadData & 0x4000) != 0 ) + { + f_pIntFlags->fErrorH100ClkA = TRUE; + pErrorStats->ulH100ClkABadCnt++; + } + if ( (usReadData & 0x8000) != 0 ) + { + if ( f_pApiInstance->pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + { + f_pIntFlags->fErrorH100ClkB = TRUE; + pErrorStats->ulH100ClkBBadCnt++; + } + } + + pIntrptManage->usRegister302h = usReadData; + /*=======================================================================*/ + } + else + { + pIntrptManage->usRegister302h = 0x0; + } + + /* TDMIE registers. */ + if ( (f_ulRegister210h & 0x00010) != 0 ) + { + /*=======================================================================*/ + /* Read register. */ + ReadParams.ulReadAddress = 0x502; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check which interrupts were set. */ + if ( (usReadData & 0x0002) != 0 ) + { + f_pIntFlags->ulFatalGeneralFlags |= cOCT6100_FATAL_GENERAL_ERROR_TYPE_3; + f_pIntFlags->fFatalGeneral = TRUE; + pErrorStats->fFatalChipError = TRUE; + } + + pIntrptManage->usRegister502h = usReadData; + /*=======================================================================*/ + } + else + { + pIntrptManage->usRegister502h = 0x0; + } + + /* PGSP registers. */ + if ( (f_ulRegister210h & 0x00080) != 0 ) + { + /*=======================================================================*/ + /* Read register. */ + ReadParams.ulReadAddress = 0x702; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check which interrupts were set. */ + if ( (usReadData & 0x0002) != 0 ) + { + f_pIntFlags->fErrorOverflowToneEvents = TRUE; + pErrorStats->ulOverflowToneEventsCnt++; + } + + pIntrptManage->usRegister702h = usReadData; + /*=======================================================================*/ + } + else + { + pIntrptManage->usRegister702h = 0x0; + } + + + + /* If this is the first time the ISR is called, clear the ISR is not called bit */ + /* in external memory to signal the remote client that we are called. */ + if ( pSharedInfo->IntrptManage.fIsrCalled == FALSE ) + { + /* Remember that we are being called. */ + pSharedInfo->IntrptManage.fIsrCalled = TRUE; + + if ( pSharedInfo->DebugInfo.fIsIsrCalledField == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.IsIsrCalledFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.IsIsrCalledFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.IsIsrCalledFieldOfst.byFieldSize; + + ulResult = Oct6100ApiReadDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + &ulTempData ); + + /* Read previous value set in the feature field. */ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + /* Clear the field. */ + ulTempData &= (~ulMask); + + /* Write the DWORD where the field is located.*/ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateIntrptStates + +Description: Updates the state of all interrupt register groups. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pIntFlags Interrupt flags. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateIntrptStates +UINT32 Oct6100ApiUpdateIntrptStates( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ) +{ + tPOCT6100_API_INTRPT_CONFIG pIntrptConfig; + tPOCT6100_API_INTRPT_MANAGE pIntrptManage; + + pIntrptConfig = &f_pApiInstance->pSharedInfo->IntrptConfig; + pIntrptManage = &f_pApiInstance->pSharedInfo->IntrptManage; + + /*-----------------------------------------------------------------------*/ + if ( ( f_pIntFlags->fFatalReadTimeout == TRUE) && + pIntrptConfig->byFatalMemoryConfig == cOCT6100_INTERRUPT_TIMEOUT && + pIntrptManage->byFatalMemoryState == cOCT6100_INTRPT_ACTIVE ) + { + pIntrptManage->byFatalMemoryState = cOCT6100_INTRPT_WILL_TIMEOUT; + pIntrptManage->ulFatalMemoryDisableMclkHigh = pIntrptManage->ulRegMclkTimeHigh; + pIntrptManage->ulFatalMemoryDisableMclkLow = pIntrptManage->ulRegMclkTimeLow; + } + /*-----------------------------------------------------------------------*/ + if ( (f_pIntFlags->fErrorRefreshTooLate == TRUE || + f_pIntFlags->fErrorPllJitter == TRUE ) && + pIntrptConfig->byErrorMemoryConfig == cOCT6100_INTERRUPT_TIMEOUT && + pIntrptManage->byErrorMemoryState == cOCT6100_INTRPT_ACTIVE ) + { + pIntrptManage->byErrorMemoryState = cOCT6100_INTRPT_WILL_TIMEOUT; + pIntrptManage->ulErrorMemoryDisableMclkHigh = pIntrptManage->ulRegMclkTimeHigh; + pIntrptManage->ulErrorMemoryDisableMclkLow = pIntrptManage->ulRegMclkTimeLow; + } + /*-----------------------------------------------------------------------*/ + if ( (f_pIntFlags->fErrorOverflowToneEvents == TRUE) && + pIntrptConfig->byErrorOverflowToneEventsConfig == cOCT6100_INTERRUPT_TIMEOUT && + pIntrptManage->byErrorOverflowToneEventsState == cOCT6100_INTRPT_ACTIVE ) + { + pIntrptManage->byErrorOverflowToneEventsState = cOCT6100_INTRPT_WILL_TIMEOUT; + pIntrptManage->ulErrorOverflowToneEventsDisableMclkHigh = pIntrptManage->ulRegMclkTimeHigh; + pIntrptManage->ulErrorOverflowToneEventsDisableMclkLow = pIntrptManage->ulRegMclkTimeLow; + } + /*-----------------------------------------------------------------------*/ + if ( (f_pIntFlags->fErrorH100OutOfSync == TRUE || + f_pIntFlags->fErrorH100ClkA == TRUE || + f_pIntFlags->fErrorH100ClkB == TRUE || + f_pIntFlags->fErrorH100FrameA == TRUE ) && + pIntrptConfig->byErrorH100Config == cOCT6100_INTERRUPT_TIMEOUT && + pIntrptManage->byErrorH100State == cOCT6100_INTRPT_ACTIVE ) + { + pIntrptManage->byErrorH100State = cOCT6100_INTRPT_WILL_TIMEOUT; + pIntrptManage->ulErrorH100DisableMclkHigh = pIntrptManage->ulRegMclkTimeHigh; + pIntrptManage->ulErrorH100DisableMclkLow = pIntrptManage->ulRegMclkTimeLow; + } + /*-----------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteIntrptRegs + +Description: Writes to interrupt registers to clear interrupt condition, and + writes to an interrupt's IE register if interrupt is to time + out. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteIntrptRegs +UINT32 Oct6100ApiWriteIntrptRegs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_API_INTRPT_MANAGE pIntrptManage; + tOCT6100_WRITE_PARAMS WriteParams; + + UINT32 ulResult; + + /* Get some local pointers. */ + pIntrptManage = &f_pApiInstance->pSharedInfo->IntrptManage; + + /* Set some parameters of write struct. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + + + /*===========================================================================*/ + if ( pIntrptManage->byFatalMemoryState == cOCT6100_INTRPT_WILL_TIMEOUT ) + { + WriteParams.ulWriteAddress = 0x104; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + if ( (pIntrptManage->usRegister102h & cOCT6100_INTRPT_MASK_REG_102H) != 0 ) + { + WriteParams.ulWriteAddress = 0x102; + WriteParams.usWriteData = pIntrptManage->usRegister102h; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + /*===========================================================================*/ + + /*===========================================================================*/ + if ( pIntrptManage->byFatalMemoryState == cOCT6100_INTRPT_WILL_TIMEOUT || + pIntrptManage->byErrorMemoryState == cOCT6100_INTRPT_WILL_TIMEOUT ) + { + WriteParams.ulWriteAddress = 0x204; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->byFatalMemoryState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x1800; + + if ( pIntrptManage->byErrorMemoryState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x0401; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + if ( (pIntrptManage->usRegister202h & cOCT6100_INTRPT_MASK_REG_202H) != 0 ) + { + WriteParams.ulWriteAddress = 0x202; + WriteParams.usWriteData = pIntrptManage->usRegister202h; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + /*===========================================================================*/ + + /*===========================================================================*/ + if ( pIntrptManage->byErrorH100State == cOCT6100_INTRPT_WILL_TIMEOUT ) + { + WriteParams.ulWriteAddress = 0x304; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->fMclkIntrptActive == TRUE ) + WriteParams.usWriteData |= 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + if ( (pIntrptManage->usRegister302h & cOCT6100_INTRPT_MASK_REG_302H) != 0 ) + { + WriteParams.ulWriteAddress = 0x302; + WriteParams.usWriteData = pIntrptManage->usRegister302h; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + /*===========================================================================*/ + + /*===========================================================================*/ + if ( (pIntrptManage->usRegister502h & cOCT6100_INTRPT_MASK_REG_502H) != 0 ) + { + WriteParams.ulWriteAddress = 0x502; + WriteParams.usWriteData = pIntrptManage->usRegister502h; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + /*===========================================================================*/ + + /*===========================================================================*/ + if ( pIntrptManage->byErrorOverflowToneEventsState == cOCT6100_INTRPT_WILL_TIMEOUT ) + { + WriteParams.ulWriteAddress = 0x704; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + if ( (pIntrptManage->usRegister702h & cOCT6100_INTRPT_MASK_REG_702H) != 0 ) + { + WriteParams.ulWriteAddress = 0x702; + WriteParams.usWriteData = pIntrptManage->usRegister702h; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + /*===========================================================================*/ + + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteIeRegs + +Description: Writes the IE field of each interrupt register. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteIeRegs +UINT32 Oct6100ApiWriteIeRegs( + tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_API_INTRPT_MANAGE pIntrptManage; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Get some local pointers. */ + pIntrptManage = &f_pApiInstance->pSharedInfo->IntrptManage; + + /* Set some parameters of write struct. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /*==================================================================================*/ + WriteParams.ulWriteAddress = 0x104; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->byFatalMemoryState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*==================================================================================*/ + + /*==================================================================================*/ + WriteParams.ulWriteAddress = 0x204; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->byFatalMemoryState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x1800; + if ( pIntrptManage->byErrorMemoryState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x0401; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*==================================================================================*/ + + /*==================================================================================*/ + WriteParams.ulWriteAddress = 0x304; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->fMclkIntrptActive == TRUE ) + WriteParams.usWriteData |= 0x0001; + if ( pIntrptManage->byErrorH100State == cOCT6100_INTRPT_ACTIVE ) + { + if ( f_pApiInstance->pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + WriteParams.usWriteData |= 0xD100; + else + WriteParams.usWriteData |= 0x5100; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*==================================================================================*/ + + /*==================================================================================*/ + WriteParams.ulWriteAddress = 0x504; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->byFatalGeneralState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*==================================================================================*/ + + /*==================================================================================*/ + WriteParams.ulWriteAddress = 0x704; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->byErrorOverflowToneEventsState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*==================================================================================*/ + + + /*==================================================================================*/ + /* Enable the GLOBAL IEs for the interrupt pin. */ + WriteParams.ulWriteAddress = 0x218; + WriteParams.usWriteData = 0x00D7; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*==================================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReadChipMclkTime + +Description: Reads the chip's mclk cycle count to construct a chip time. + The time is used to manage interrupts. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReadChipMclkTime +UINT32 Oct6100ApiReadChipMclkTime( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_API_INTRPT_MANAGE pIntrptManage; + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulCheckData; + UINT32 ulResult; + UINT32 i; + UINT16 usReadData; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + pIntrptManage = &pSharedInfo->IntrptManage; + + /* Assign memory for read data. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Perform reads. */ + for ( i = 0; i < 100; i++ ) + { + ReadParams.ulReadAddress = 0x306; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + pIntrptManage->ulRegMclkTimeHigh = usReadData & 0xFF; + ulCheckData = usReadData; + + ReadParams.ulReadAddress = 0x308; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + pIntrptManage->ulRegMclkTimeLow = (usReadData & 0xFFFF) << 16; + + ReadParams.ulReadAddress = 0x306; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + if ( ulCheckData == usReadData ) + break; + } + + if ( i == 100 ) + return cOCT6100_ERR_FATAL_2F; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateIntrptTimeouts + +Description: Checks which interrupt groups have finished their timeout + period. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateIntrptTimeouts +UINT32 Oct6100ApiUpdateIntrptTimeouts( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_API_INTRPT_MANAGE pIntrptManage; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulRegMclkTimePlus5MsHigh; + UINT32 ulRegMclkTimePlus5MsLow; + UINT32 ulResult; + BOOL fFatalMemoryChange = FALSE; + BOOL fDataErrMemoryChange = FALSE; + BOOL fErrorOverflowToneEventsChange = FALSE; + BOOL fH100ErrorChange = FALSE; + + /* Get local pointer to interrupt management structure. */ + pIntrptManage = &f_pApiInstance->pSharedInfo->IntrptManage; + + /* Calculate mclk time + 5 ms. */ + ulRegMclkTimePlus5MsLow = pIntrptManage->ulRegMclkTimeLow + (5 * pIntrptManage->ulNumMclkCyclesIn1Ms); + if ( ulRegMclkTimePlus5MsLow < pIntrptManage->ulRegMclkTimeLow ) + ulRegMclkTimePlus5MsHigh = pIntrptManage->ulRegMclkTimeHigh + 1; + else /* ( ulRegMclkTimePlus5MsLow >= pIntrptManage->ulRegMclkTimeLow ) */ + ulRegMclkTimePlus5MsHigh = pIntrptManage->ulRegMclkTimeHigh; + + /* Check which interrupts are timed out and need to be reenabled now. */ + if ( pIntrptManage->byFatalMemoryState == cOCT6100_INTRPT_IN_TIMEOUT ) + { + mOCT6100_CHECK_INTRPT_TIMEOUT( ulRegMclkTimePlus5MsHigh, ulRegMclkTimePlus5MsLow, pIntrptManage->ulFatalMemoryDisableMclkHigh, pIntrptManage->ulFatalMemoryDisableMclkLow, pIntrptManage->ulFatalMemoryEnableMclkHigh, pIntrptManage->ulFatalMemoryEnableMclkLow, pIntrptManage->byFatalMemoryState, fFatalMemoryChange ) + } + if ( pIntrptManage->byErrorMemoryState == cOCT6100_INTRPT_IN_TIMEOUT ) + { + mOCT6100_CHECK_INTRPT_TIMEOUT( ulRegMclkTimePlus5MsHigh, ulRegMclkTimePlus5MsLow, pIntrptManage->ulErrorMemoryDisableMclkHigh, pIntrptManage->ulErrorMemoryDisableMclkLow, pIntrptManage->ulErrorMemoryEnableMclkHigh, pIntrptManage->ulErrorMemoryEnableMclkLow, pIntrptManage->byErrorMemoryState, fDataErrMemoryChange ) + } + if ( pIntrptManage->byErrorOverflowToneEventsState == cOCT6100_INTRPT_IN_TIMEOUT ) + { + mOCT6100_CHECK_INTRPT_TIMEOUT( ulRegMclkTimePlus5MsHigh, ulRegMclkTimePlus5MsLow, pIntrptManage->ulErrorOverflowToneEventsDisableMclkHigh, pIntrptManage->ulErrorOverflowToneEventsDisableMclkLow, pIntrptManage->ulErrorOverflowToneEventsEnableMclkHigh, pIntrptManage->ulErrorOverflowToneEventsEnableMclkLow, pIntrptManage->byErrorOverflowToneEventsState, fErrorOverflowToneEventsChange ) + } + if ( pIntrptManage->byErrorH100State == cOCT6100_INTRPT_IN_TIMEOUT ) + { + mOCT6100_CHECK_INTRPT_TIMEOUT( ulRegMclkTimePlus5MsHigh, ulRegMclkTimePlus5MsLow, pIntrptManage->ulErrorH100DisableMclkHigh, pIntrptManage->ulErrorH100DisableMclkLow, pIntrptManage->ulErrorH100EnableMclkHigh, pIntrptManage->ulErrorH100EnableMclkLow, pIntrptManage->byErrorH100State, fH100ErrorChange ) + } + + /* Set some parameters of write struct. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Write to the IE registers which have changed. */ + + /*==================================================================================*/ + if ( fFatalMemoryChange == TRUE ) + { + WriteParams.ulWriteAddress = 0x104; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->byFatalMemoryState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + } + /*==================================================================================*/ + + /*==================================================================================*/ + if ( fFatalMemoryChange == TRUE || + fDataErrMemoryChange == TRUE ) + { + WriteParams.ulWriteAddress = 0x204; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->byFatalMemoryState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x1800; + if ( pIntrptManage->byErrorMemoryState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x0401; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + } + /*==================================================================================*/ + + /*==================================================================================*/ + if ( pIntrptManage->fMclkIntrptActive == TRUE || + fH100ErrorChange == TRUE ) + { + WriteParams.ulWriteAddress = 0x304; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->fMclkIntrptActive == TRUE ) + WriteParams.usWriteData |= 0x0001; + + if ( pIntrptManage->byErrorH100State == cOCT6100_INTRPT_ACTIVE ) + { + if ( f_pApiInstance->pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + WriteParams.usWriteData |= 0xD100; + else + WriteParams.usWriteData |= 0x5100; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + } + /*==================================================================================*/ + + + /*==================================================================================*/ + if ( fErrorOverflowToneEventsChange == TRUE ) + { + WriteParams.ulWriteAddress = 0x704; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->byErrorOverflowToneEventsState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + } + /*==================================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiScheduleNextMclkIntrptSer + +Description: Serialized sub-function of Oct6100ApiScheduleNextMclkIntrpt. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiScheduleNextMclkIntrptSer +UINT32 Oct6100ApiScheduleNextMclkIntrptSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_INTRPT_CONFIG pIntrptConfig; + tPOCT6100_API_INTRPT_MANAGE pIntrptManage; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulTimeDiff; + UINT32 ulRegMclkTimeHigh; + UINT32 ulRegMclkTimeLow; + UINT32 ulResult; + BOOL fConditionFlag = TRUE; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain temporary pointers to reduce indirection, thus speeding up processing. */ + pIntrptConfig = &pSharedInfo->IntrptConfig; + pIntrptManage = &pSharedInfo->IntrptManage; + ulRegMclkTimeHigh = pIntrptManage->ulRegMclkTimeHigh; + ulRegMclkTimeLow = pIntrptManage->ulRegMclkTimeLow; + + /* First, check if any interrupts have just been disabled. If there are any, */ + /* determine the time at which they should be reenabled. */ + pIntrptManage->ulNextMclkIntrptTimeHigh = cOCT6100_INVALID_VALUE; + pIntrptManage->ulNextMclkIntrptTimeLow = cOCT6100_INVALID_VALUE; + + while ( fConditionFlag ) + { + /* Indicate that no mclk interrupt is needed, yet. */ + ulTimeDiff = cOCT6100_INVALID_VALUE; + + /* Check each interrupt category to see if an mclk interrupt is needed to */ + /* reenable an interrupt at a later time. */ + if ( pIntrptManage->byFatalMemoryState != cOCT6100_INTRPT_ACTIVE && + pIntrptManage->byFatalMemoryState != cOCT6100_INTRPT_DISABLED ) + { + mOCT6100_GET_INTRPT_ENABLE_TIME( ulRegMclkTimeHigh, ulRegMclkTimeLow, pIntrptManage->byFatalMemoryState, pIntrptManage->ulFatalMemoryEnableMclkHigh, pIntrptManage->ulFatalMemoryEnableMclkLow, pIntrptConfig->ulFatalMemoryTimeoutMclk, ulTimeDiff ) + } + if ( pIntrptManage->byErrorMemoryState != cOCT6100_INTRPT_ACTIVE && + pIntrptManage->byErrorMemoryState != cOCT6100_INTRPT_DISABLED ) + { + mOCT6100_GET_INTRPT_ENABLE_TIME( ulRegMclkTimeHigh, ulRegMclkTimeLow, pIntrptManage->byErrorMemoryState, pIntrptManage->ulErrorMemoryEnableMclkHigh, pIntrptManage->ulErrorMemoryEnableMclkLow, pIntrptConfig->ulErrorMemoryTimeoutMclk, ulTimeDiff ) + } + if ( pIntrptManage->byErrorOverflowToneEventsState != cOCT6100_INTRPT_ACTIVE && + pIntrptManage->byErrorOverflowToneEventsState != cOCT6100_INTRPT_DISABLED ) + { + mOCT6100_GET_INTRPT_ENABLE_TIME( ulRegMclkTimeHigh, ulRegMclkTimeLow, pIntrptManage->byErrorOverflowToneEventsState, pIntrptManage->ulErrorOverflowToneEventsEnableMclkHigh, pIntrptManage->ulErrorOverflowToneEventsEnableMclkLow, pIntrptConfig->ulErrorOverflowToneEventsTimeoutMclk, ulTimeDiff ) + } + if ( pIntrptManage->byErrorH100State != cOCT6100_INTRPT_ACTIVE && + pIntrptManage->byErrorH100State != cOCT6100_INTRPT_DISABLED ) + { + mOCT6100_GET_INTRPT_ENABLE_TIME( ulRegMclkTimeHigh, ulRegMclkTimeLow, pIntrptManage->byErrorH100State, pIntrptManage->ulErrorH100EnableMclkHigh, pIntrptManage->ulErrorH100EnableMclkLow, pIntrptConfig->ulErrorH100TimeoutMclk, ulTimeDiff ) + } + + /* Set some parameters of write struct. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Schedule next mclk interrupt, if any is needed. */ + if ( ulTimeDiff != cOCT6100_INVALID_VALUE ) + { + UINT32 ulMclkTimeTest; + UINT32 ulAlarmTimeTest; + UINT32 ulTimeDiffTest; + BOOL fAlarmTimePassed; + + /* Indicate that an mclk interrupt is scheduled.*/ + pIntrptManage->fMclkIntrptActive = TRUE; + + pIntrptManage->ulNextMclkIntrptTimeLow = ulRegMclkTimeLow + ulTimeDiff; + if ( pIntrptManage->ulNextMclkIntrptTimeLow < ulRegMclkTimeLow ) + pIntrptManage->ulNextMclkIntrptTimeHigh = ulRegMclkTimeHigh + 1; + else /* ( pIntrptManage->ulNextMclkIntrptTimeLow >= ulRegMclkTimeLow ) */ + pIntrptManage->ulNextMclkIntrptTimeHigh = ulRegMclkTimeHigh; + + WriteParams.ulWriteAddress = 0x30C; + WriteParams.usWriteData = (UINT16)( (pIntrptManage->ulNextMclkIntrptTimeLow >> 24) & 0xFF ); + WriteParams.usWriteData |= (UINT16)( (pIntrptManage->ulNextMclkIntrptTimeHigh & 0xFF) << 8 ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x30E; + WriteParams.usWriteData = (UINT16)( (pIntrptManage->ulNextMclkIntrptTimeLow >> 8) & 0xFFFF ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x304; + WriteParams.usWriteData = 0; + + if ( pIntrptManage->fMclkIntrptActive == TRUE ) + WriteParams.usWriteData = 0x0001; + + if ( pIntrptManage->byErrorH100State == cOCT6100_INTRPT_ACTIVE ) + { + if ( f_pApiInstance->pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + WriteParams.usWriteData |= 0xD100; + else + WriteParams.usWriteData |= 0x5100; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Disable the ROL if previously set. */ + WriteParams.ulWriteAddress = 0x302; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if already passed the next interrupt time. */ + ulResult = Oct6100ApiReadChipMclkTime( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulMclkTimeTest = (pIntrptManage->ulRegMclkTimeLow >> 16) & 0xFFFF; + ulAlarmTimeTest = (pIntrptManage->ulNextMclkIntrptTimeLow >> 16) & 0xFFFF; + + /* Update the local Mlck timer values.*/ + ulRegMclkTimeHigh = pIntrptManage->ulRegMclkTimeHigh; + ulRegMclkTimeLow = pIntrptManage->ulRegMclkTimeLow; + + fAlarmTimePassed = FALSE; + + if ( ulMclkTimeTest > ulAlarmTimeTest ) + { + ulTimeDiffTest = ulMclkTimeTest - ulAlarmTimeTest; + if ( ulTimeDiffTest <= 0x8000 ) + fAlarmTimePassed = TRUE; + } + else /* ( ulMclkTimeTest <= ulAlarmTimeTest ) */ + { + ulTimeDiffTest = ulAlarmTimeTest - ulMclkTimeTest; + if ( ulTimeDiffTest > 0x8000 ) + fAlarmTimePassed = TRUE; + } + + if ( fAlarmTimePassed == TRUE ) + { + /* Passed the interrupt time. Schedule next interrupt (if needed). */ + ulResult = Oct6100ApiUpdateIntrptTimeouts( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + continue; + } + else + { + fConditionFlag = FALSE; + } + } + else + { + /* Indicate that no mclk interrupt is scheduled. */ + pIntrptManage->fMclkIntrptActive = FALSE; + + /* Insure that the mclk interrupt is not enabled. */ + WriteParams.ulWriteAddress = 0x304; + WriteParams.usWriteData = 0x0000; + if ( pIntrptManage->byErrorH100State == cOCT6100_INTRPT_ACTIVE ) + { + if ( f_pApiInstance->pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + WriteParams.usWriteData |= 0xD100; + else + WriteParams.usWriteData |= 0x5100; + } + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + fConditionFlag = FALSE; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckProcessorState + +Description: This function verifies if the NLP and AF processors are operating + correctly. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pIntFlags Pointer to a tOCT6100_INTERRUPT_FLAGS structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckProcessorState +UINT32 Oct6100ApiCheckProcessorState( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_READ_BURST_PARAMS ReadBurstParams; + + UINT32 ulNlpTimestamp; + UINT32 ulAfTimestamp; + UINT32 ulTimestampDiff; + + UINT32 ulResult; + UINT32 i; + + UINT16 usReadData; + UINT16 ausReadData[ 2 ]; + + UINT32 aulWaitTime[ 2 ]; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set some parameters of write struct. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Set some parameters of write struct. */ + ReadBurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadBurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadBurstParams.pusReadData = ausReadData; + + /*-----------------------------------------------------------------------*/ + /* Check if chip is in reset. */ + + /* Read the main control register. */ + ReadParams.ulReadAddress = 0x100; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData == 0x0000 ) + { + /* Chip was resetted. */ + f_pIntFlags->ulFatalGeneralFlags |= cOCT6100_FATAL_GENERAL_ERROR_TYPE_4; + f_pIntFlags->fFatalGeneral = TRUE; + pSharedInfo->ErrorStats.fFatalChipError = TRUE; + } + + /*-----------------------------------------------------------------------*/ + + + /*-----------------------------------------------------------------------*/ + /* Reading the AF timestamp.*/ + + for ( i = 0; i < cOCT6100_MAX_LOOP; i++ ) + { + /* Read the timestamp.*/ + ReadBurstParams.ulReadAddress = 0x082E0008; + ReadBurstParams.ulReadLength = 2; + + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Read the high part again to make sure it didn't wrap. */ + ReadParams.ulReadAddress = 0x082E0008; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the low part wrapped. */ + if ( ausReadData[ 0 ] == usReadData ) + break; + } + + if ( i == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_INTRPTS_AF_TIMESTAMP_READ_TIMEOUT; + + /* Save the AF timestamp. */ + ulAfTimestamp = (ausReadData[ 0 ] << 16) | ausReadData[ 1 ]; + + /*-----------------------------------------------------------------------*/ + + + /*-----------------------------------------------------------------------*/ + /* Reading the NLP timestamp. */ + + for ( i = 0; i < cOCT6100_MAX_LOOP; i++ ) + { + /* Read the timestamp. */ + ReadBurstParams.ulReadAddress = 0x08000008; + ReadBurstParams.ulReadLength = 2; + + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Read the high part again to make sure it didn't wrap. */ + ReadParams.ulReadAddress = 0x08000008; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the low part wrapped. */ + if ( ausReadData[ 0 ] == usReadData ) + break; + } + + if ( i == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_INTRPTS_NLP_TIMESTAMP_READ_TIMEOUT; + + /* Save the NLP timestamp. */ + ulNlpTimestamp = (ausReadData[ 0 ] << 16) | ausReadData[ 1 ]; + + /*-----------------------------------------------------------------------*/ + + + /*-----------------------------------------------------------------------*/ + /* Check the validity of the timestamp. */ + + if ( ulAfTimestamp > ulNlpTimestamp ) + { + /* The NLP timestamp wrapped. */ + ulTimestampDiff = 0xFFFFFFFF - ulAfTimestamp + 1; + ulTimestampDiff += ulNlpTimestamp; + } + else + ulTimestampDiff = ulNlpTimestamp - ulAfTimestamp; + + if ( ulTimestampDiff > 0x2000 ) + { + f_pIntFlags->ulFatalGeneralFlags |= cOCT6100_FATAL_GENERAL_ERROR_TYPE_5; + f_pIntFlags->fFatalGeneral = TRUE; + pSharedInfo->ErrorStats.fFatalChipError = TRUE; + } + + /*Check if AF and NLP are both stuck*/ + if ( f_pIntFlags->fErrorH100ClkA == FALSE && + f_pIntFlags->fErrorH100ClkB == FALSE && + f_pIntFlags->fErrorH100FrameA == FALSE && + f_pIntFlags->fErrorH100OutOfSync == FALSE ) + + { + if ( ulAfTimestamp == 0 && ulNlpTimestamp == 0 ) + { + /*Give some time to the counters*/ + aulWaitTime[ 0 ] = 250; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*Let's read again the AF timestamp to be sure. Maybe they were at 0 at the same time*/ + ReadBurstParams.ulReadAddress = 0x082E0008; + ReadBurstParams.ulReadLength = 2; + + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulAfTimestamp = (ausReadData[ 0 ] << 16) | ausReadData[ 1 ]; + + if ( ulAfTimestamp == 0 ) + { + /*TDM Clocks are ok but NLP and AF timestamps are both at 0*/ + f_pIntFlags->ulFatalGeneralFlags |= cOCT6100_FATAL_GENERAL_ERROR_TYPE_9; + f_pIntFlags->fFatalGeneral = TRUE; + pSharedInfo->ErrorStats.fFatalChipError = TRUE; + } + } + + } + + /*-----------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_memory.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_memory.c new file mode 100644 index 0000000..b2c0e8e --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_memory.c @@ -0,0 +1,831 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_memory.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the functions used to manage the allocation of memory + blocks in external memory. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 42 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_playout_buf_inst.h" +#include "oct6100api/oct6100_api_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_memory_priv.h" + + +/**************************** PRIVATE FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetMemorySwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of the memories. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pOpenChip Pointer to chip configuration struct. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetMemorySwSizes +UINT32 Oct6100ApiGetMemorySwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + UINT32 ulNumTsiChariots; + + /*=========================================================================*/ + /* Internal memory */ + + /* Evaluate the number of available TSI memory after reserving the ones used by channels. */ + ulNumTsiChariots = cOCT6100_TOTAL_TSI_CONTROL_MEM_ENTRY - f_pOpenChip->ulMaxPhasingTssts - cOCT6100_TSI_MEM_FOR_TIMESTAMP; + + if ( f_pOpenChip->fEnableExtToneDetection == TRUE ) + ulNumTsiChariots--; + + /* Calculate memory needed for TSI memory allocation. */ + ulResult = OctapiLlmAllocGetSize( ulNumTsiChariots, &f_pInstSizes->ulTsiMemoryAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_94; + + /* Calculate memory needed for conversion memory allocation. */ + ulResult = OctapiLlmAllocGetSize( cOCT6100_MAX_CONVERSION_MEMORY_BLOCKS, &f_pInstSizes->ulConversionMemoryAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_B5; + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulTsiMemoryAlloc, ulTempVar ); + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulConversionMemoryAlloc, ulTempVar ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiMemorySwInit + +Description: Initializes all elements of the instance structure associated + to memories. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiMemorySwInit +UINT32 Oct6100ApiMemorySwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pTsiMemAlloc; + PVOID pAllocPnt; + UINT32 ulResult; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /*=========================================================================*/ + /* Internal memory */ + + /* Initialize the TSI memory allocation structure. */ + pSharedInfo->MemoryMap.ulNumTsiEntries = cOCT6100_TOTAL_TSI_CONTROL_MEM_ENTRY - pSharedInfo->ChipConfig.usMaxPhasingTssts - cOCT6100_TSI_MEM_FOR_TIMESTAMP; + + if ( pSharedInfo->ChipConfig.fEnableExtToneDetection == TRUE ) + pSharedInfo->MemoryMap.ulNumTsiEntries--; + + mOCT6100_GET_TSI_MEMORY_ALLOC_PNT( pSharedInfo, pTsiMemAlloc ); + + ulResult = OctapiLlmAllocInit( &pTsiMemAlloc, pSharedInfo->MemoryMap.ulNumTsiEntries ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_95; + + /* Initialize the conversion memory allocation structure. */ + mOCT6100_GET_CONVERSION_MEMORY_ALLOC_PNT( pSharedInfo, pAllocPnt ); + + ulResult = OctapiLlmAllocInit( &pAllocPnt, cOCT6100_MAX_CONVERSION_MEMORY_BLOCKS ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_B6; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBufferPlayoutMemorySwInit + +Description: Initialize the buffer playout memory allocation working + structures. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBufferPlayoutMemorySwInit +UINT32 Oct6100ApiBufferPlayoutMemorySwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE pNode; + UINT32 i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Only if buffer playout will be used. */ + if ( pSharedInfo->ChipConfig.usMaxPlayoutBuffers > 0 ) + { + mOCT6100_GET_BUFFER_MEMORY_NODE_LIST_PNT( pSharedInfo, pNode ); + + /* First node contains all free memory at beginning. This node is not used, but represents the memory. */ + pNode->ulSize = ( pSharedInfo->MiscVars.ulTotalMemSize + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) - pSharedInfo->MemoryMap.ulFreeMemBaseAddress; + pNode->ulNext = 0; + pNode->ulPrevious = 0; + pNode->fAllocated = FALSE; + pNode->ulStartAddress = pSharedInfo->MemoryMap.ulFreeMemBaseAddress; + + pNode++; + + /* Now create the first node of the free list, i.e. nodes that can be used later for modeling the memory. */ + pNode->ulSize = 0; + /* Next free. */ + pNode->ulNext = 2; + /* Last. */ + pNode->ulPrevious = ( pSharedInfo->ChipConfig.usMaxPlayoutBuffers * 2 ) - 1; + pNode->fAllocated = FALSE; + pNode->ulStartAddress = 0; + + pNode++; + + /* Link all the unused nodes. */ + for( i = 2; i < (UINT32)( ( pSharedInfo->ChipConfig.usMaxPlayoutBuffers * 2 ) - 1 ); i ++ ) + { + pNode->ulNext = i + 1; + pNode->ulPrevious = i - 1; + pNode->ulStartAddress = 0; + pNode->ulSize = 0; + pNode->fAllocated = FALSE; + pNode++; + } + + /* Last node of the unused list. */ + pNode->fAllocated = FALSE; + pNode->ulPrevious = ( pSharedInfo->ChipConfig.usMaxPlayoutBuffers * 2 ) - 2; + /* Free list head. */ + pNode->ulNext = 1; + pNode->ulSize = 0; + pNode->ulStartAddress = 0; + + /* Set roving pointer to first node ( which can be used! ) */ + pSharedInfo->PlayoutInfo.ulRovingNode = 0; + + /* First unused node. */ + pSharedInfo->PlayoutInfo.ulFirstUnusedNode = 1; + + /* Last unused node. */ + pSharedInfo->PlayoutInfo.ulLastUnusedNode = ( pSharedInfo->ChipConfig.usMaxPlayoutBuffers * 2 ) - 1; + + /* Number of unused nodes. */ + pSharedInfo->PlayoutInfo.ulUnusedNodeCnt = ( pSharedInfo->ChipConfig.usMaxPlayoutBuffers * 2 ) - 1; + } + else + { + pSharedInfo->PlayoutInfo.ulUnusedNodeCnt = 0; + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveBufferPlayoutMemoryNode + +Description: Get a free node from the unused buffer playout node list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pulNewNode The index of the node. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveBufferPlayoutMemoryNode +UINT32 Oct6100ApiReserveBufferPlayoutMemoryNode( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT32 f_pulNewNode ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE pNode; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check if a free block is left. */ + if ( pSharedInfo->PlayoutInfo.ulUnusedNodeCnt == 0 ) + { + /* This should not happen according to the allocated list from the beginning. */ + return cOCT6100_ERR_FATAL_CC; + } + + /* The new node is the first in the unused list. */ + *f_pulNewNode = pSharedInfo->PlayoutInfo.ulFirstUnusedNode; + + /* Unlink this new node from the unused list. */ + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pNode, *f_pulNewNode ); + + pSharedInfo->PlayoutInfo.ulFirstUnusedNode = pNode->ulNext; + + pNode->ulPrevious = pSharedInfo->PlayoutInfo.ulLastUnusedNode; + + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pNode, pSharedInfo->PlayoutInfo.ulLastUnusedNode ); + + pNode->ulNext = pSharedInfo->PlayoutInfo.ulFirstUnusedNode; + + /* Update unused node count. */ + pSharedInfo->PlayoutInfo.ulUnusedNodeCnt--; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseBufferPlayoutMemoryNode + +Description: Release a node that is not used anymore. Insert this node + into the unused list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulOldNode The index of the node. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseBufferPlayoutMemoryNode +UINT32 Oct6100ApiReleaseBufferPlayoutMemoryNode( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulOldNode ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE pNode; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get the last unused node. Insert this old node at the end of the unused list. */ + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pNode, pSharedInfo->PlayoutInfo.ulLastUnusedNode ); + + /* Last node points to old node. */ + pNode->ulNext = f_ulOldNode; + + /* Update old node. */ + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pNode, f_ulOldNode ); + + pNode->ulPrevious = pSharedInfo->PlayoutInfo.ulLastUnusedNode; + pNode->ulNext = pSharedInfo->PlayoutInfo.ulFirstUnusedNode; + pSharedInfo->PlayoutInfo.ulLastUnusedNode = f_ulOldNode; + + /* Keep unused node count. */ + pSharedInfo->PlayoutInfo.ulUnusedNodeCnt++; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveBufferPlayoutMemory + +Description: Try to allocate requested size. + Returns an error if malloc point could not be found. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulSize Needed size. +f_pulMallocAddress Alloc point. This memory can now be used. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveBufferPlayoutMemory +UINT32 Oct6100ApiReserveBufferPlayoutMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulSize, + OUT PUINT32 f_pulMallocAddress ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE pCurrentNode; + tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE pTempNode; + tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE pNewNode; + + UINT32 ulCurrentBufferPlayoutMallocNode; + UINT32 ulNewNode; + BOOL fFoundMemory = FALSE; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Requested size must be divisible by 64. */ + if ( f_ulSize % 64 ) + { + f_ulSize = f_ulSize + ( 64 - ( f_ulSize % 64 ) ); + } + + /* Start with roving pointer. */ + ulCurrentBufferPlayoutMallocNode = pSharedInfo->PlayoutInfo.ulRovingNode; + + *f_pulMallocAddress = 0; + + /* Return an error if size requested is zero. */ + if ( f_ulSize == 0 ) + { + return cOCT6100_ERR_BUFFER_PLAYOUT_MALLOC_ZERO; + } + + do + { + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pCurrentNode, ulCurrentBufferPlayoutMallocNode ); + + /* Look for a free node big enough to fulfill user requested size. */ + if ( ( pCurrentNode->fAllocated == FALSE ) && ( pCurrentNode->ulSize >= f_ulSize ) ) + { + /* Use this node! */ + pCurrentNode->fAllocated = TRUE; + + if ( pCurrentNode->ulNext != 0 ) + { + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pTempNode, pCurrentNode->ulNext ); + + if( ( pTempNode->fAllocated == TRUE ) && ( pCurrentNode->ulSize > f_ulSize ) ) + { + /* Fragmentation NOW! */ + + /* Allocate new node that will contain free size. */ + ulResult = Oct6100ApiReserveBufferPlayoutMemoryNode( f_pApiInstance, &ulNewNode ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pNewNode, ulNewNode ); + + /* Can use this free node. */ + pNewNode->ulSize = pCurrentNode->ulSize - f_ulSize; + pNewNode->ulStartAddress = pCurrentNode->ulStartAddress + f_ulSize; + + /* Link new node into the list. */ + pNewNode->ulNext = pCurrentNode->ulNext; + pNewNode->ulPrevious = ulCurrentBufferPlayoutMallocNode; + pNewNode->fAllocated = FALSE; + pTempNode->ulPrevious = ulNewNode; + pCurrentNode->ulNext = ulNewNode; + } + } + else if ( pCurrentNode->ulSize > f_ulSize ) + { + /* Must allocate a new free node for the rest of the space. */ + ulResult = Oct6100ApiReserveBufferPlayoutMemoryNode( f_pApiInstance, &ulNewNode ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pNewNode, ulNewNode ); + + pNewNode->ulNext = pCurrentNode->ulNext; + pCurrentNode->ulNext = ulNewNode; + pNewNode->ulPrevious = ulCurrentBufferPlayoutMallocNode; + pNewNode->fAllocated = FALSE; + pNewNode->ulSize = pCurrentNode->ulSize - f_ulSize; + pNewNode->ulStartAddress = pCurrentNode->ulStartAddress + f_ulSize; + + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pTempNode, 0 ); + + /* Check for the head node that would have to be updated. */ + if ( ( ulCurrentBufferPlayoutMallocNode == 0 ) && ( pTempNode->ulPrevious == 0 ) ) + pTempNode->ulPrevious = ulNewNode; + } + else + { + /* Perfect fit. */ + } + pCurrentNode->ulSize = f_ulSize; + + /* Update roving pointer. */ + pSharedInfo->PlayoutInfo.ulRovingNode = ulCurrentBufferPlayoutMallocNode; + *f_pulMallocAddress = pCurrentNode->ulStartAddress; + fFoundMemory = TRUE; + break; + } + + /* Next block! */ + ulCurrentBufferPlayoutMallocNode = pCurrentNode->ulNext; + + } while ( pSharedInfo->PlayoutInfo.ulRovingNode != ulCurrentBufferPlayoutMallocNode ); + + if ( fFoundMemory == FALSE ) + { + return cOCT6100_ERR_BUFFER_PLAYOUT_NO_MEMORY; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseBufferPlayoutMemory + +Description: Free what was allocated at address. Free is somewhat slower + then Malloc. O(n), must travel through the list looking for + the malloc point. Return an error if alloc point was not found. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulMallocAddress Alloc point. The memory at address will be freed. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseBufferPlayoutMemory +UINT32 Oct6100ApiReleaseBufferPlayoutMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulMallocAddress ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE pCurrentNode; + tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE pTempNode; + tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE pOldNode; + + UINT32 ulResult = cOCT6100_ERR_BUFFER_PLAYOUT_MALLOC_POINT_NOT_FOUND; + UINT32 ulNodeToMerge; + UINT32 ulNodeToRemove; + UINT32 ulCurrentBufferPlayoutMallocNode; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Start from the beginning and find the alloc node. */ + ulCurrentBufferPlayoutMallocNode = 0; + + do + { + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pCurrentNode, ulCurrentBufferPlayoutMallocNode ); + + if ( ( pCurrentNode->ulStartAddress == f_ulMallocAddress ) && ( pCurrentNode->fAllocated == TRUE ) ) + { + /* We found the block! */ + pCurrentNode->fAllocated = FALSE; + + /* Check if the next node can be merged. */ + if ( pCurrentNode->ulNext != 0 ) + { + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pTempNode, pCurrentNode->ulNext ); + + if ( pTempNode->fAllocated == FALSE ) + { + /* Can merge this block to us. */ + pCurrentNode->ulSize += pTempNode->ulSize; + pTempNode->ulSize = 0; + + /* Unlink unused node. */ + ulNodeToRemove = pCurrentNode->ulNext; + pCurrentNode->ulNext = pTempNode->ulNext; + + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pTempNode, pCurrentNode->ulNext ); + + pTempNode->ulPrevious = ulCurrentBufferPlayoutMallocNode; + + ulResult = Oct6100ApiReleaseBufferPlayoutMemoryNode( f_pApiInstance, ulNodeToRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move roving pointer if have to. */ + if ( pSharedInfo->PlayoutInfo.ulRovingNode == ulNodeToRemove ) + pSharedInfo->PlayoutInfo.ulRovingNode = ulCurrentBufferPlayoutMallocNode; + } + } + + /* Check if previous node can merge. */ + if ( ulCurrentBufferPlayoutMallocNode != 0 ) + { + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pTempNode, pCurrentNode->ulPrevious ); + + if ( pTempNode->fAllocated == FALSE ) + { + ulNodeToMerge = pCurrentNode->ulPrevious; + + /* Can merge us to this node. */ + pTempNode->ulSize += pCurrentNode->ulSize; + pCurrentNode->ulSize = 0; + + /* Unlink unused node. */ + ulNodeToRemove = ulCurrentBufferPlayoutMallocNode; + + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pOldNode, ulNodeToRemove ); + + pTempNode->ulNext = pOldNode->ulNext; + + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pTempNode, pTempNode->ulNext ); + + pTempNode->ulPrevious = ulNodeToMerge; + + pOldNode->fAllocated = FALSE; + pOldNode->ulSize = 0; + pOldNode->ulStartAddress = 0; + + /* Move roving pointer if have to. */ + if ( pSharedInfo->PlayoutInfo.ulRovingNode == ulNodeToRemove ) + pSharedInfo->PlayoutInfo.ulRovingNode = ulNodeToMerge; + + /* Release this unused node. */ + ulResult = Oct6100ApiReleaseBufferPlayoutMemoryNode( f_pApiInstance, ulNodeToRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* All's good! */ + ulResult = 0; + break; + } + + /* Next node. */ + ulCurrentBufferPlayoutMallocNode = pCurrentNode->ulNext; + + } while( ulCurrentBufferPlayoutMallocNode != 0 ); + + return ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveTsiMemEntry + +Description: Reserves a TSI chariot memory entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pusTsiMemIndex Resulting index reserved in the TSI chariot memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveTsiMemEntry +UINT32 Oct6100ApiReserveTsiMemEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusTsiMemIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pTsiMemAlloc; + UINT32 ulResult; + UINT32 ulIndex; + UINT32 ulNumTsiB4Timestamp; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_TSI_MEMORY_ALLOC_PNT( pSharedInfo, pTsiMemAlloc ) + + ulResult = OctapiLlmAllocAlloc( pTsiMemAlloc, &ulIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_MEMORY_ALL_TSI_MEM_ENTRY_RESERVED; + else + return cOCT6100_ERR_FATAL_92; + } + + + if ( ulIndex >= cOCT6100_NUM_TSI_B4_PHASING ) + { + /* Evaluate the number of TSI memory before the timestamp TSI. */ + ulNumTsiB4Timestamp = cOCT6100_NUM_TSI_B4_PHASING + cOCT6100_MAX_TSI_B4_TIMESTAMP - pSharedInfo->ChipConfig.usMaxPhasingTssts; + + if ( ulIndex >= ulNumTsiB4Timestamp ) + { + /* + 4 for the timestamp TSI entries.*/ + *f_pusTsiMemIndex = (UINT16)( pSharedInfo->ChipConfig.usMaxPhasingTssts + ulIndex + cOCT6100_TSI_MEM_FOR_TIMESTAMP ); + } + else /* ulIndex < ulNumTsiB4Timestamp */ + { + *f_pusTsiMemIndex = (UINT16)( pSharedInfo->ChipConfig.usMaxPhasingTssts + ulIndex ); + } + } + else /* ulIndex < ulNumTsiB4Timestamp */ + { + *f_pusTsiMemIndex = (UINT16)( ulIndex ); + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseTsiMemEntry + +Description: Releases a TSI chariot memory entry specified. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usTsiMemIndex Index reserved in the TSI chariot memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseTsiMemEntry +UINT32 Oct6100ApiReleaseTsiMemEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsiMemIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pTsiMemAlloc; + UINT32 ulResult; + UINT32 ulIndex; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check if the entry programmed is greater then the timestamp entries. */ + if ( f_usTsiMemIndex > cOCT6100_TSST_CONTROL_TIMESTAMP_BASE_ENTRY ) + ulIndex = f_usTsiMemIndex - cOCT6100_TSI_MEM_FOR_TIMESTAMP; + else + ulIndex = f_usTsiMemIndex; + + /* Check if the entry programmed is greater then the phasing TSST entries. */ + if ( ulIndex > cOCT6100_TSST_CONTROL_PHASING_TSST_BASE_ENTRY ) + ulIndex -= pSharedInfo->ChipConfig.usMaxPhasingTssts; + + mOCT6100_GET_TSI_MEMORY_ALLOC_PNT( pSharedInfo, pTsiMemAlloc ) + + ulResult = OctapiLlmAllocDealloc( pTsiMemAlloc, ulIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_93; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveConversionMemEntry + +Description: Reserves one of the conversion memory entry + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to + keep the present state of the chip and all its + resources. + +f_pusConversionMemIndex Resulting index reserved in the conversion memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveConversionMemEntry +UINT32 Oct6100ApiReserveConversionMemEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusConversionMemIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pConversionMemAlloc; + UINT32 ulConversionMemIndex; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_CONVERSION_MEMORY_ALLOC_PNT( pSharedInfo, pConversionMemAlloc ) + + ulResult = OctapiLlmAllocAlloc( pConversionMemAlloc, &ulConversionMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_MEMORY_ALL_CONVERSION_MEM_ENTRY_RESERVED; + else + return cOCT6100_ERR_FATAL_B8; + } + + *f_pusConversionMemIndex = (UINT16)( ulConversionMemIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseConversionMemEntry + +Description: Releases the conversion chariot memory entry specified. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to + keep the present state of the chip and all its + resources. + +f_usConversionMemIndex Index reserved in the conversion chariot memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseConversionMemEntry +UINT32 Oct6100ApiReleaseConversionMemEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usConversionMemIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pConversionMemAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_CONVERSION_MEMORY_ALLOC_PNT( pSharedInfo, pConversionMemAlloc ) + + ulResult = OctapiLlmAllocDealloc( pConversionMemAlloc, f_usConversionMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_B7; + } + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_miscellaneous.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_miscellaneous.c new file mode 100644 index 0000000..4e5c189 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_miscellaneous.c @@ -0,0 +1,640 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_miscellaneous.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains miscellaneous functions used in various files. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 35 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" + +#include "apilib/octapi_largmath.h" + +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_channel_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_miscellaneous_priv.h" + + +/**************************** PRIVATE FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWaitForTime + +Description: Waits for the specified amount of time. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_aulWaitTime[ 2 ] The amout of time to be waited. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWaitForTime +UINT32 Oct6100ApiWaitForTime( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_aulWaitTime[ 2 ] ) +{ + tOCT6100_GET_TIME StartTime; + tOCT6100_GET_TIME CurrentTime; + UINT32 aulTimeDelta[ 2 ]; + UINT32 ulResult; + UINT16 usTempVar; + BOOL fConditionFlag = TRUE; + + /* Copy the process context. */ + StartTime.pProcessContext = f_pApiInstance->pProcessContext; + CurrentTime.pProcessContext = f_pApiInstance->pProcessContext; + + ulResult = Oct6100UserGetTime( &StartTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + while ( fConditionFlag ) + { + ulResult = Oct6100UserGetTime( &CurrentTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = octapi_lm_subtract( + CurrentTime.aulWallTimeUs, 1, + StartTime.aulWallTimeUs, 1, + aulTimeDelta, 1, + &usTempVar ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_37; + + if ( aulTimeDelta[ 1 ] >= f_aulWaitTime[ 1 ] && + aulTimeDelta[ 0 ] >= f_aulWaitTime[ 0 ] ) + fConditionFlag = FALSE; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWaitForPcRegisterBit + +Description: Polls the specified PC register bit. The function exits once + the bit is cleared by hardware, or when the specified timeout + period has been expired. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulPcRegAdd Address of the register containing the PC bit. +f_ulPcBitNum Number of the PC bit within the register. +f_ulValue Expected value of the bit. +f_ulTimeoutUs The timeout period, in usec. +f_pfBitEqual Pointer to the result of the bit comparison. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWaitForPcRegisterBit +UINT32 Oct6100ApiWaitForPcRegisterBit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulPcRegAdd, + IN UINT32 f_ulPcBitNum, + IN UINT32 f_ulValue, + IN UINT32 f_ulTimeoutUs, + OUT PBOOL f_pfBitEqual ) +{ + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_GET_TIME StartTime; + tOCT6100_GET_TIME TimeoutTime; + tOCT6100_GET_TIME CurrentTime; + UINT32 ulResult; + UINT16 usReadData; + BOOL fConditionFlag = TRUE; + + /* Copy the process context. */ + StartTime.pProcessContext = f_pApiInstance->pProcessContext; + CurrentTime.pProcessContext = f_pApiInstance->pProcessContext; + + /* Get the current system time. */ + ulResult = Oct6100UserGetTime( &StartTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Mark the bit as not being equal, for now. */ + *f_pfBitEqual = FALSE; + + /* Determine the time at which the timeout has expired. */ + ulResult = octapi_lm_add( + StartTime.aulWallTimeUs, 1, + &f_ulTimeoutUs, 0, + TimeoutTime.aulWallTimeUs, 1 ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Prepare read structure. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.ulReadAddress = f_ulPcRegAdd; + ReadParams.pusReadData = &usReadData; + + /* Read the PC bit while the timeout period hasn't expired. */ + while ( fConditionFlag ) + { + /* Read the current time again to check for timeout. */ + ulResult = Oct6100UserGetTime( &CurrentTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100UserDriverReadApi( &ReadParams ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( ( UINT16 )((usReadData >> f_ulPcBitNum) & 0x1) == ( UINT16 )f_ulValue ) + { + /* Mark the bit as being equal. */ + *f_pfBitEqual = TRUE; + fConditionFlag = FALSE; + } + + if ( CurrentTime.aulWallTimeUs[ 1 ] > TimeoutTime.aulWallTimeUs[ 1 ] || + (CurrentTime.aulWallTimeUs[ 1 ] == TimeoutTime.aulWallTimeUs[ 1 ] && + CurrentTime.aulWallTimeUs[ 0 ] >= TimeoutTime.aulWallTimeUs[ 0 ]) ) + fConditionFlag = FALSE; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReadDword + +Description: Read a DWORD at specified address in external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulAddress DWORD address where to read. +f_pulReadData Resulting data. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReadDword +UINT32 Oct6100ApiReadDword( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulAddress, + OUT PUINT32 f_pulReadData ) +{ + tOCT6100_READ_PARAMS ReadParams; + UINT16 usReadData; + + UINT32 ulResult; + UINT32 ulTempData; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /*==================================================================================*/ + /* Read the first 16 bits. */ + ReadParams.ulReadAddress = f_ulAddress; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulTempData = usReadData << 16; + + /* Read the last 16 bits. */ + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulTempData |= usReadData; + + /*==================================================================================*/ + + /* Return the read value.*/ + *f_pulReadData = ulTempData; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteDword + +Description: Write a DWORD at specified address in external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulAddress DWORD address where to write. +f_ulWriteData DWORD data to write. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteDword +UINT32 Oct6100ApiWriteDword( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulAddress, + IN UINT32 f_ulWriteData ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Write the first 16 bits. */ + WriteParams.ulWriteAddress = f_ulAddress; + WriteParams.usWriteData = (UINT16)((f_ulWriteData >> 16) & 0xFFFF); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write the last word. */ + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)(f_ulWriteData & 0xFFFF); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCreateFeatureMask + +Description: + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_ulFieldSize Size of the field, in bits. +f_ulFieldBitOffset Bit offset, from the least significant bit. +f_pulFieldMask Resulting mask. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCreateFeatureMask +VOID Oct6100ApiCreateFeatureMask( + IN UINT32 f_ulFieldSize, + IN UINT32 f_ulFieldBitOffset, + OUT PUINT32 f_pulFieldMask ) +{ + UINT32 ulMask; + UINT32 i; + + ulMask = 0; + + /* Create the mask based on the field size. */ + for ( i = 0; i < f_ulFieldSize; i++ ) + { + ulMask <<= 1; + ulMask |= 1; + } + + /* Once the mask is of the desired size, offset it to fit the field */ + /* within the DWORD read. */ + ulMask <<= f_ulFieldBitOffset; + + /* Return the mask. */ + *f_pulFieldMask = ulMask; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiStrStr + +Description: OCT6100 API version of strstr() + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pszSource Source string to analyze. +f_pszString String to look for. +f_pszLastCharPtr Last character in the source string. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiStrStr +unsigned char const *Oct6100ApiStrStr( + IN unsigned char const *f_pszSource, + IN unsigned char const *f_pszString, + IN unsigned char const *f_pszLastCharPtr ) +{ + UINT32 ulCurrentPos; + UINT32 ulStringLength; + UINT32 ulNumMatchingCharFound = 0; + unsigned char const *pchFirstChar = NULL; + UINT32 ulSourceLength; + + if ( f_pszLastCharPtr < f_pszSource ) + return NULL; + + ulSourceLength = (UINT32)( f_pszLastCharPtr - f_pszSource ); + ulStringLength = Oct6100ApiStrLen( f_pszString ); + + for ( ulCurrentPos = 0; ulCurrentPos < ulSourceLength; ulCurrentPos++ ) + { + /* Check if the character matches. */ + if ( f_pszSource[ ulCurrentPos ] == f_pszString[ ulNumMatchingCharFound ] ) + { + if ( ulNumMatchingCharFound == 0 ) + pchFirstChar = ( f_pszSource + ulCurrentPos ); + + ulNumMatchingCharFound++; + + /* Check if the whole string matched. */ + if ( ulNumMatchingCharFound == ulStringLength ) + break; + } + else if ( ulNumMatchingCharFound != 0 ) + { + ulNumMatchingCharFound = 0; + + /* Reset the search, but take a look at the current character. It might */ + /* be the beginning of the string we are looking for. */ + if ( f_pszSource[ ulCurrentPos ] == f_pszString[ ulNumMatchingCharFound ] ) + { + pchFirstChar = ( f_pszSource + ulCurrentPos ); + ulNumMatchingCharFound++; + + /* Check if the whole string matched. */ + /* This check must be done in case we have the 1 character strstr */ + if ( ulNumMatchingCharFound == ulStringLength ) + break; + } + } + } + + if ( ulCurrentPos == ulSourceLength ) + return NULL; + else + return pchFirstChar; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiStrLen + +Description: OCT6100 API version of strlen() + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pszString Source string to count length of. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiStrLen +UINT32 Oct6100ApiStrLen( + IN unsigned char const *f_pszString ) +{ + UINT32 ulCount = 0; + + while( f_pszString[ ulCount ] != '\0' ) + ulCount++; + + return ulCount; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAsciiToHex + +Description: Convert an ASCII character to an hexadecimal value. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_chCharacter ASCII character to convert. +f_pulValue Resulting hexadecimal value. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAsciiToHex +UINT32 Oct6100ApiAsciiToHex( + IN UINT8 f_chCharacter, + OUT PUINT32 f_pulValue ) +{ + switch ( f_chCharacter ) + { + case '0': + (*f_pulValue) = 0x0; + break; + case '1': + (*f_pulValue) = 0x1; + break; + case '2': + (*f_pulValue) = 0x2; + break; + case '3': + (*f_pulValue) = 0x3; + break; + case '4': + (*f_pulValue) = 0x4; + break; + case '5': + (*f_pulValue) = 0x5; + break; + case '6': + (*f_pulValue) = 0x6; + break; + case '7': + (*f_pulValue) = 0x7; + break; + case '8': + (*f_pulValue) = 0x8; + break; + case '9': + (*f_pulValue) = 0x9; + break; + case 'A': + case 'a': + (*f_pulValue) = 0xA; + break; + case 'B': + case 'b': + (*f_pulValue) = 0xB; + break; + case 'C': + case 'c': + (*f_pulValue) = 0xC; + break; + case 'D': + case 'd': + (*f_pulValue) = 0xD; + break; + case 'E': + case 'e': + (*f_pulValue) = 0xE; + break; + case 'F': + case 'f': + (*f_pulValue) = 0xF; + break; + default: + (*f_pulValue) = 0x0; + return cOCT6100_ERR_MISC_ASCII_CONVERSION_FAILED; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiHexToAscii + +Description: Convert an hexadecimal value to an ASCII character. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_ulNumber Hexadecimal value to convert. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiHexToAscii +UINT8 Oct6100ApiHexToAscii( + IN UINT32 f_ulNumber ) +{ + if ( f_ulNumber >= 0xA ) + return (UINT8)( 55 + f_ulNumber ); /* Hex values from 0xA to 0xF */ + else + return (UINT8)( 48 + f_ulNumber ); /* Hex values from 0x0 to 0x9 */ +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRand + +Description: Random number generator. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_ulRange Range of the random number to be generated. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRand +UINT32 Oct6100ApiRand( + IN UINT32 f_ulRange ) +{ + static UINT32 ulRandomSeed = 0x12345678; + UINT32 ulBit0; + + UINT32 i, j; + UINT16 ulWithinRange = FALSE; + + UINT32 ulResult = cOCT6100_ERR_OK; + UINT16 ulLoop; + + UINT32 ulRangeMask; + UINT32 ulAddedValue; + + + ulRangeMask = 1; + ulLoop = TRUE; + i = 1; + + while ( ulLoop ) + { + + ulAddedValue = 2; + for ( j = 1; j < i; j++ ) + ulAddedValue *= 2; + + ulRangeMask = ulRangeMask + ulAddedValue; + + if ( ulRangeMask >= f_ulRange ) + ulLoop = FALSE; + + i++; + } + + while ( !ulWithinRange ) + { + ulBit0 = ((ulRandomSeed >> 19) & 0x1) ^ ((ulRandomSeed >> 16) & 0x1); + ulRandomSeed = ((ulRandomSeed << 1) & 0xFFFFF) | ulBit0; + + ulResult = ulRandomSeed & ulRangeMask; + + if ( ulResult <= f_ulRange ) + ulWithinRange = TRUE; + } + + return ulResult; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.c new file mode 100644 index 0000000..05aff3b --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.c @@ -0,0 +1,1586 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_mixer.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the functions used to manage the allocation of mixer + blocks in memories. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 42 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_mixer_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_mixer_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_mixer_priv.h" + +/**************************** PUBLIC FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100MixerCopyEventCreate + +Description: This function creates a mixer copy event used to copy + information from one channel port to another channel port. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pCopyEventCreate Pointer to a mixer copy event structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100MixerCopyEventCreateDef +UINT32 Oct6100MixerCopyEventCreateDef( + tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate ) +{ + f_pCopyEventCreate->pulCopyEventHndl = NULL; + + f_pCopyEventCreate->ulSourceChanHndl = cOCT6100_INVALID_HANDLE; + f_pCopyEventCreate->ulSourcePort = cOCT6100_INVALID_PORT; + + f_pCopyEventCreate->ulDestinationChanHndl = cOCT6100_INVALID_HANDLE; + f_pCopyEventCreate->ulDestinationPort = cOCT6100_INVALID_PORT; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100MixerCopyEventCreate +UINT32 Oct6100MixerCopyEventCreate( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100MixerCopyEventCreateSer( f_pApiInstance, f_pCopyEventCreate ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100MixerCopyEventDestroy + +Description: This function destroys a mixer copy event used to copy + information from one channel port to another. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pCopyEventDestroy Pointer to a destroy copy event structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100MixerCopyEventDestroyDef +UINT32 Oct6100MixerCopyEventDestroyDef( + tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy ) +{ + f_pCopyEventDestroy->ulCopyEventHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100MixerCopyEventDestroy +UINT32 Oct6100MixerCopyEventDestroy( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100MixerCopyEventDestroySer( f_pApiInstance, f_pCopyEventDestroy ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetMixerSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of mixer events. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pOpenChip User chip configuration. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetMixerSwSizes +UINT32 Oct6100ApiGetMixerSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + + /* Calculate the API memory required for the resource entry lists. */ + f_pInstSizes->ulMixerEventList = cOCT6100_MAX_MIXER_EVENTS * sizeof( tOCT6100_API_MIXER_EVENT ); + + /* Calculate memory needed for mixers entry allocation. */ + ulResult = OctapiLlmAllocGetSize( cOCT6100_MAX_MIXER_EVENTS, &f_pInstSizes->ulMixerEventAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1D; + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulMixerEventList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulMixerEventAlloc, ulTempVar ) + + + f_pInstSizes->ulCopyEventList = cOCT6100_MAX_MIXER_EVENTS * sizeof( tOCT6100_API_COPY_EVENT ); + + ulResult = OctapiLlmAllocGetSize( cOCT6100_MAX_MIXER_EVENTS, &f_pInstSizes->ulCopyEventAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1D; + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulCopyEventList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulCopyEventAlloc, ulTempVar ) + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiMixerSwInit + +Description: Initializes all elements of the instance structure associated + to the mixer events. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This mixer is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiMixerSwInit +UINT32 Oct6100ApiMixerSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_MIXER_EVENT pMixerEventList; + PVOID pMixerEventAlloc; + PVOID pCopyEventAlloc; + UINT32 ulTempVar; + UINT32 ulResult; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /*===================================================================*/ + /* Initialize the mixer event list. */ + mOCT6100_GET_MIXER_EVENT_LIST_PNT( pSharedInfo, pMixerEventList ); + + /* Initialize the mixer event allocation software to "all free". */ + Oct6100UserMemSet( pMixerEventList, 0x00, cOCT6100_MAX_MIXER_EVENTS * sizeof( tOCT6100_API_MIXER_EVENT )); + + mOCT6100_GET_MIXER_EVENT_ALLOC_PNT( pSharedInfo, pMixerEventAlloc ) + + ulResult = OctapiLlmAllocInit( &pMixerEventAlloc, cOCT6100_MAX_MIXER_EVENTS ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1F; + + /* Now reserve the first entry as the first node. */ + ulResult = OctapiLlmAllocAlloc( pMixerEventAlloc, &ulTempVar ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_20; + } + + /* Check that we obtain the first event. */ + if ( ulTempVar != 0 ) + return cOCT6100_ERR_FATAL_21; + + /* Now reserve the tail entry. */ + ulResult = OctapiLlmAllocAlloc( pMixerEventAlloc, &ulTempVar ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_AA; + } + /* Check that we obtain the first event. */ + if ( ulTempVar != 1 ) + return cOCT6100_ERR_FATAL_AB; + + /* Program the head node. */ + pMixerEventList[ cOCT6100_MIXER_HEAD_NODE ].fReserved = TRUE; + pMixerEventList[ cOCT6100_MIXER_HEAD_NODE ].usNextEventPtr = cOCT6100_MIXER_TAIL_NODE; + pMixerEventList[ cOCT6100_MIXER_HEAD_NODE ].usEventType = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + /* Program the tail node. */ + pMixerEventList[ cOCT6100_MIXER_TAIL_NODE ].fReserved = TRUE; + pMixerEventList[ cOCT6100_MIXER_TAIL_NODE ].usNextEventPtr = cOCT6100_INVALID_INDEX; + pMixerEventList[ cOCT6100_MIXER_TAIL_NODE ].usEventType = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + /* Now reserve the entry used for channel recording if the feature is enabled. */ + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + { + UINT32 ulAllocIndex; + + /* Reserve an entry to copy the desire SOUT signal to the SIN signal of the recording channel. */ + ulResult = OctapiLlmAllocAlloc( pMixerEventAlloc, &ulAllocIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_90; + } + + pSharedInfo->MixerInfo.usRecordCopyEventIndex = (UINT16)( ulAllocIndex & 0xFFFF ); + + /* Reserve an entry to copy the saved SIN signal of the debugged channel into it's original location. */ + ulResult = OctapiLlmAllocAlloc( pMixerEventAlloc, &ulAllocIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_90; + } + + pSharedInfo->MixerInfo.usRecordSinEventIndex = (UINT16)( ulAllocIndex & 0xFFFF ); + + /* Configure the SIN event. */ + pMixerEventList[ pSharedInfo->MixerInfo.usRecordSinEventIndex ].fReserved = TRUE; + pMixerEventList[ pSharedInfo->MixerInfo.usRecordSinEventIndex ].usNextEventPtr = cOCT6100_MIXER_TAIL_NODE; + pMixerEventList[ pSharedInfo->MixerInfo.usRecordSinEventIndex ].usEventType = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + /* Configure the SOUT copy event. */ + pMixerEventList[ pSharedInfo->MixerInfo.usRecordCopyEventIndex ].fReserved = TRUE; + pMixerEventList[ pSharedInfo->MixerInfo.usRecordCopyEventIndex ].usNextEventPtr = pSharedInfo->MixerInfo.usRecordSinEventIndex; + pMixerEventList[ pSharedInfo->MixerInfo.usRecordCopyEventIndex ].usEventType = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + /* Program the head node. */ + pMixerEventList[ cOCT6100_MIXER_HEAD_NODE ].usNextEventPtr = pSharedInfo->MixerInfo.usRecordCopyEventIndex; + } + + /* Initialize the copy event list. */ + mOCT6100_GET_COPY_EVENT_ALLOC_PNT( pSharedInfo, pCopyEventAlloc ) + + ulResult = OctapiLlmAllocInit( &pCopyEventAlloc, cOCT6100_MAX_MIXER_EVENTS ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_B4; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiMixerEventAdd + +Description: This function adds a mixer event event to the list of events + based on the event type passed to the function. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. +f_usEventIndex Index of the event within the API's mixer event list. +f_usEventType Type of mixer event. +f_usDestinationChanIndex Index of the destination channel within the API's + channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiMixerEventAdd +UINT32 Oct6100ApiMixerEventAdd( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEventIndex, + IN UINT16 f_usEventType, + IN UINT16 f_usDestinationChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_MIXER_EVENT pCurrentEventEntry; + tPOCT6100_API_MIXER_EVENT pTempEventEntry; + tPOCT6100_API_CHANNEL pDestinationEntry; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + UINT16 usTempEventIndex; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Get a pointer to the event entry. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pCurrentEventEntry, f_usEventIndex ); + + /* Get a pointer to the destination channel entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pDestinationEntry, f_usDestinationChanIndex ); + + /* Now proceed according to the event type. */ + switch ( f_usEventType ) + { + case cOCT6100_EVENT_TYPE_SOUT_COPY: + + /* Now insert the Sin copy event */ + if ( pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr == cOCT6100_INVALID_INDEX ) + { + /* The only node in the list before the point where the node needs to */ + /* be inserted is the head node. */ + usTempEventIndex = cOCT6100_MIXER_HEAD_NODE; + + /* This node will be the first one in the Sout copy section. */ + pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr = f_usEventIndex; + pSharedInfo->MixerInfo.usLastSoutCopyEventPtr = f_usEventIndex; + } + else /* pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr != cOCT6100_INVALID_INDEX */ + { + usTempEventIndex = pSharedInfo->MixerInfo.usLastSoutCopyEventPtr; + pSharedInfo->MixerInfo.usLastSoutCopyEventPtr = f_usEventIndex; + } + + break; + + case cOCT6100_EVENT_TYPE_SIN_COPY: + + /* Now insert the Sin copy event. */ + if ( pSharedInfo->MixerInfo.usFirstSinCopyEventPtr == cOCT6100_INVALID_INDEX ) + { + /* This is the first Sin copy event. We must find the event that comes before */ + /* the event we want to add. First let's check for a bridge event. */ + if ( pSharedInfo->MixerInfo.usLastBridgeEventPtr == cOCT6100_INVALID_INDEX ) + { + /* No event in the bridge section, now let's check in the Sout copy section. */ + if ( pSharedInfo->MixerInfo.usLastSoutCopyEventPtr == cOCT6100_INVALID_INDEX ) + { + /* The only node in the list then is the head node. */ + usTempEventIndex = cOCT6100_MIXER_HEAD_NODE; + } + else + { + usTempEventIndex = pSharedInfo->MixerInfo.usLastSoutCopyEventPtr; + } + } + else + { + usTempEventIndex = pSharedInfo->MixerInfo.usLastBridgeEventPtr; + } + + /* This node will be the first one in the Sin copy section. */ + pSharedInfo->MixerInfo.usFirstSinCopyEventPtr = f_usEventIndex; + pSharedInfo->MixerInfo.usLastSinCopyEventPtr = f_usEventIndex; + } + else /* pSharedInfo->MixerInfo.usFirstSinCopyEventPtr != cOCT6100_INVALID_INDEX */ + { + usTempEventIndex = pSharedInfo->MixerInfo.usLastSinCopyEventPtr; + pSharedInfo->MixerInfo.usLastSinCopyEventPtr = f_usEventIndex; + } + + break; + + default: + return cOCT6100_ERR_FATAL_AF; + + } + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, usTempEventIndex ); + + /*=======================================================================*/ + /* Program the Copy event. */ + + /* Set the Copy event first. */ + pCurrentEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_COPY; + pCurrentEventEntry->usNextEventPtr = pTempEventEntry->usNextEventPtr; + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + WriteParams.usWriteData = pCurrentEventEntry->usNextEventPtr; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Modify the previous node. */ + + /* Set the last Sub-store entry. */ + pTempEventEntry->usNextEventPtr = f_usEventIndex; + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usTempEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + WriteParams.usWriteData = f_usEventIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Save the destination channel index, needed when removing the event from the mixer. */ + pCurrentEventEntry->usDestinationChanIndex = f_usDestinationChanIndex; + + /* Mark the entry as reserved. */ + pCurrentEventEntry->fReserved = TRUE; + + /* Increment the event count on that particular destination channel */ + pDestinationEntry->usMixerEventCnt++; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiMixerEventRemove + +Description: This function removes a mixer event event from the list of events based + on the event type passed to the function. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usEventIndex Index of event within the API's mixer event list. +f_usEventType Type of mixer event. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiMixerEventRemove +UINT32 Oct6100ApiMixerEventRemove( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEventIndex, + IN UINT16 f_usEventType ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_MIXER_EVENT pCurrentEventEntry; + tPOCT6100_API_MIXER_EVENT pTempEventEntry; + tPOCT6100_API_CHANNEL pDestinationEntry; + tOCT6100_WRITE_BURST_PARAMS BurstWriteParams; + tOCT6100_WRITE_PARAMS WriteParams; + BOOL fFirstSinCopyEvent = FALSE; + UINT32 ulResult; + UINT16 usTempEventIndex; + UINT32 ulLoopCount = 0; + UINT16 ausWriteData[ 4 ] = { 0 }; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + BurstWriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstWriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + BurstWriteParams.pusWriteData = ausWriteData; + BurstWriteParams.ulWriteLength = 4; + + /* Get a pointer to the event entry. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pCurrentEventEntry, f_usEventIndex ); + + /* Get the pointer to the channel entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pDestinationEntry, pCurrentEventEntry->usDestinationChanIndex ); + + /* Now proceed according to the event type. */ + switch ( f_usEventType ) + { + case cOCT6100_EVENT_TYPE_SOUT_COPY: + + if ( f_usEventIndex == pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr ) + { + usTempEventIndex = cOCT6100_MIXER_HEAD_NODE; + } + else + { + /* Now insert the Sin copy event. */ + usTempEventIndex = pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr; + } + + /* Find the copy entry before the entry to remove. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, usTempEventIndex ); + + while( pTempEventEntry->usNextEventPtr != f_usEventIndex ) + { + usTempEventIndex = pTempEventEntry->usNextEventPtr; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, usTempEventIndex ); + + ulLoopCount++; + if ( ulLoopCount == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_FATAL_B2; + } + + /*=======================================================================*/ + /* Update the global mixer pointers. */ + if ( f_usEventIndex == pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr ) + { + if ( f_usEventIndex == pSharedInfo->MixerInfo.usLastSoutCopyEventPtr ) + { + /* This event was the only of the list.*/ + pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastSoutCopyEventPtr = cOCT6100_INVALID_INDEX; + } + else + { + pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr = pCurrentEventEntry->usNextEventPtr; + } + } + else if ( f_usEventIndex == pSharedInfo->MixerInfo.usLastSoutCopyEventPtr ) + { + pSharedInfo->MixerInfo.usLastSoutCopyEventPtr = usTempEventIndex; + } + /*=======================================================================*/ + + break; + + + case cOCT6100_EVENT_TYPE_SIN_COPY: + + if ( f_usEventIndex == pSharedInfo->MixerInfo.usFirstSinCopyEventPtr ) + { + fFirstSinCopyEvent = TRUE; + + if ( pSharedInfo->MixerInfo.usLastBridgeEventPtr != cOCT6100_INVALID_INDEX ) + { + usTempEventIndex = pSharedInfo->MixerInfo.usLastBridgeEventPtr; + } + else if ( pSharedInfo->MixerInfo.usLastSoutCopyEventPtr != cOCT6100_INVALID_INDEX ) + { + usTempEventIndex = pSharedInfo->MixerInfo.usLastSoutCopyEventPtr; + } + else + { + usTempEventIndex = cOCT6100_MIXER_HEAD_NODE; + } + } + else + { + /* Now insert the Sin copy event. */ + usTempEventIndex = pSharedInfo->MixerInfo.usFirstSinCopyEventPtr; + } + + /* Find the copy entry before the entry to remove. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, usTempEventIndex ); + + /* If we are not the first event of the Sin copy list. */ + if ( fFirstSinCopyEvent == FALSE ) + { + while( pTempEventEntry->usNextEventPtr != f_usEventIndex ) + { + usTempEventIndex = pTempEventEntry->usNextEventPtr; + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, usTempEventIndex ); + + ulLoopCount++; + if ( ulLoopCount == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_FATAL_B1; + } + } + + /*=======================================================================*/ + /* Update the global mixer pointers. */ + if ( f_usEventIndex == pSharedInfo->MixerInfo.usFirstSinCopyEventPtr ) + { + if ( f_usEventIndex == pSharedInfo->MixerInfo.usLastSinCopyEventPtr ) + { + /* This event was the only of the list. */ + pSharedInfo->MixerInfo.usFirstSinCopyEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastSinCopyEventPtr = cOCT6100_INVALID_INDEX; + } + else + { + pSharedInfo->MixerInfo.usFirstSinCopyEventPtr = pCurrentEventEntry->usNextEventPtr; + } + } + else if ( f_usEventIndex == pSharedInfo->MixerInfo.usLastSinCopyEventPtr ) + { + pSharedInfo->MixerInfo.usLastSinCopyEventPtr = usTempEventIndex; + } + /*=======================================================================*/ + + break; + + default: + return cOCT6100_ERR_FATAL_B0; + + } + + /*=======================================================================*/ + /* Modify the previous event. */ + + pTempEventEntry->usNextEventPtr = pCurrentEventEntry->usNextEventPtr; + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usTempEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + WriteParams.usWriteData = pTempEventEntry->usNextEventPtr; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Clear the current event. */ + + BurstWriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + mOCT6100_DRIVER_WRITE_BURST_API( BurstWriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Decrement the mixer event count active on that channel. */ + pDestinationEntry->usMixerEventCnt--; + + /*=======================================================================*/ + + + /*=======================================================================*/ + + /* This index of this channel is not valid anymore! */ + pCurrentEventEntry->usDestinationChanIndex = cOCT6100_INVALID_INDEX; + + /* Mark this entry as free. */ + pCurrentEventEntry->fReserved = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100MixerCopyEventCreateSer + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pCopyEventCreate Pointer to a create copy event structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100MixerCopyEventCreateSer +UINT32 Oct6100MixerCopyEventCreateSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate ) +{ + UINT16 usCopyEventIndex = 0; + UINT16 usMixerEventIndex = 0; + UINT16 usSourceChanIndex; + UINT16 usDestinationChanIndex; + UINT32 ulResult; + + /* Check the user's configuration of the copy event for errors. */ + ulResult = Oct6100ApiCheckCopyEventCreateParams( f_pApiInstance, + f_pCopyEventCreate, + &usSourceChanIndex, + &usDestinationChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the copy event. */ + ulResult = Oct6100ApiReserveCopyEventCreateResources( f_pApiInstance, + &usCopyEventIndex, + &usMixerEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write all necessary structures to activate the echo cancellation channel. */ + ulResult = Oct6100ApiWriteCopyEventCreateStructs( f_pApiInstance, + f_pCopyEventCreate, + usMixerEventIndex, + usSourceChanIndex, + usDestinationChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the new echo cancellation channels's entry in the ECHO channel list. */ + ulResult = Oct6100ApiUpdateCopyEventCreateEntry( f_pApiInstance, + f_pCopyEventCreate, + usCopyEventIndex, + usMixerEventIndex, + usSourceChanIndex, + usDestinationChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckCopyEventCreateParams + +Description: Checks the user's parameter passed to the create + copy event function. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pCopyEventCreate Pointer to a create copy event structure. +f_pusSourceChanIndex Pointer to the index of the input channel. +f_pusDestinationChanIndex Pointer to the index of the output channel. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckCopyEventCreateParams +UINT32 Oct6100ApiCheckCopyEventCreateParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate, + OUT PUINT16 f_pusSourceChanIndex, + OUT PUINT16 f_pusDestinationChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pSourceEntry; + tPOCT6100_API_CHANNEL pDestinationEntry; + UINT32 ulEntryOpenCnt; + + /* Obtain shared resources pointer. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + if ( f_pCopyEventCreate->pulCopyEventHndl == NULL ) + return cOCT6100_ERR_MIXER_COPY_EVENT_HANDLE; + + if ( f_pCopyEventCreate->ulSourceChanHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_MIXER_SOURCE_CHAN_HANDLE; + if ( f_pCopyEventCreate->ulDestinationChanHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_MIXER_DESTINATION_CHAN_HANDLE; + + if ( f_pCopyEventCreate->ulSourcePort != cOCT6100_CHANNEL_PORT_RIN && + f_pCopyEventCreate->ulSourcePort != cOCT6100_CHANNEL_PORT_SIN ) + return cOCT6100_ERR_MIXER_SOURCE_PORT; + + if ( f_pCopyEventCreate->ulDestinationPort != cOCT6100_CHANNEL_PORT_RIN && + f_pCopyEventCreate->ulDestinationPort != cOCT6100_CHANNEL_PORT_SIN ) + return cOCT6100_ERR_MIXER_DESTINATION_PORT; + + /*=======================================================================*/ + /* Verify the first channel handle. */ + + if ( (f_pCopyEventCreate->ulSourceChanHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_MIXER_SOURCE_CHAN_HANDLE; + + *f_pusSourceChanIndex = (UINT16)( f_pCopyEventCreate->ulSourceChanHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusSourceChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_MIXER_SOURCE_CHAN_HANDLE; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pSourceEntry, *f_pusSourceChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pCopyEventCreate->ulSourceChanHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pSourceEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pSourceEntry->byEntryOpenCnt ) + return cOCT6100_ERR_MIXER_SOURCE_CHAN_HANDLE; + if ( pSourceEntry->CodecConfig.byDecoderPort == f_pCopyEventCreate->ulSourcePort ) + return cOCT6100_ERR_MIXER_SOURCE_ADPCM_RESOURCES_ACTIVATED; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Verify the second channel handle. */ + + if ( (f_pCopyEventCreate->ulDestinationChanHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_MIXER_DESTINATION_CHAN_HANDLE; + + *f_pusDestinationChanIndex = (UINT16)( f_pCopyEventCreate->ulDestinationChanHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusDestinationChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_MIXER_DESTINATION_CHAN_HANDLE; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pDestinationEntry, *f_pusDestinationChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pCopyEventCreate->ulDestinationChanHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pDestinationEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pDestinationEntry->byEntryOpenCnt ) + return cOCT6100_ERR_MIXER_DESTINATION_CHAN_HANDLE; + if ( pDestinationEntry->CodecConfig.byDecoderPort == f_pCopyEventCreate->ulDestinationPort ) + return cOCT6100_ERR_MIXER_DEST_ADPCM_RESOURCES_ACTIVATED; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveCopyEventCreateResources + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pusCopyEntryIndex Pointer to the index of the copy entry within the API's list. +f_pusCopyEventIndex Pointer to the index of the mixer copy event. +. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveCopyEventCreateResources +UINT32 Oct6100ApiReserveCopyEventCreateResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusCopyEntryIndex, + IN OUT PUINT16 f_pusCopyEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult = cOCT6100_ERR_OK; + UINT32 ulTempVar; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /*===============================================================================*/ + /* Verify and reserve the resources that might already be allocated. */ + + ulResult = Oct6100ApiReserveCopyEventEntry( f_pApiInstance, + f_pusCopyEntryIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Reserve the source copy event for the first channel. */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, + f_pusCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Reserve the Sin copy event for the first channel. */ + ulTempVar = Oct6100ApiReleaseCopyEventEntry ( f_pApiInstance, + *f_pusCopyEntryIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteCopyEventCreateStructs + +Description: Performs all the required structure writes to configure the + new copy event + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pCopyEventCreate Pointer to a create copy event structure. +f_usMixerEventIndex Index of the copy event within the mixer memory. +f_usSourceChanIndex Index of the source channel within the API's channel list. +f_usDestinationChanIndex Index of the destination channel within the API's channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteCopyEventCreateStructs +UINT32 Oct6100ApiWriteCopyEventCreateStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate, + IN UINT16 f_usMixerEventIndex, + IN UINT16 f_usSourceChanIndex, + IN UINT16 f_usDestinationChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pSourceEntry; + tPOCT6100_API_CHANNEL pDestinationEntry; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*==============================================================================*/ + /* Get a pointer to the two channel entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pSourceEntry, f_usSourceChanIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pDestinationEntry, f_usDestinationChanIndex ); + + /*==============================================================================*/ + /* Configure the TSST control memory and add the Sin copy event if necessary. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usMixerEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + + if ( f_pCopyEventCreate->ulSourcePort == cOCT6100_CHANNEL_PORT_RIN ) + { + WriteParams.usWriteData |= pSourceEntry->usRinRoutTsiMemIndex; + WriteParams.usWriteData |= pSourceEntry->TdmConfig.byRinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + } + else /* f_pCopyEventCreate->ulSourcePort == cOCT6100_CHANNEL_PORT_SIN */ + { + if ( pSourceEntry->usExtraSinTsiMemIndex != cOCT6100_INVALID_INDEX ) + { + WriteParams.usWriteData |= pSourceEntry->usExtraSinTsiMemIndex; + } + else + { + WriteParams.usWriteData |= pSourceEntry->usSinSoutTsiMemIndex; + } + + WriteParams.usWriteData |= pSourceEntry->TdmConfig.bySinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + + if ( f_pCopyEventCreate->ulDestinationPort == cOCT6100_CHANNEL_PORT_RIN ) + { + WriteParams.usWriteData = (UINT16)( pDestinationEntry->usRinRoutTsiMemIndex ); + } + else /* f_pCopyEventCreate->ulDestinationPort == cOCT6100_CHANNEL_PORT_SIN */ + { + WriteParams.usWriteData = (UINT16)( pDestinationEntry->usSinSoutTsiMemIndex ); + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Now insert the event into the event list. */ + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_usMixerEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY, + f_usDestinationChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Increment the copy event count on this channel. */ + pDestinationEntry->usCopyEventCnt++; + + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateCopyEventCreateEntry + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. +f_pCopyEventCreate Pointer to a create copy event structure. +f_usCopyEventIndex Index of the copy event within the API's event list. +f_usMixerEventIndex Index of the copy event within the mixer memory. +f_usSourceChanIndex Index of the source channel within the API's channel list. +f_usDestinationChanIndex Index of the destination channel within the API's channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateCopyEventCreateEntry +UINT32 Oct6100ApiUpdateCopyEventCreateEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate, + IN UINT16 f_usCopyEventIndex, + IN UINT16 f_usMixerEventIndex, + IN UINT16 f_usSourceChanIndex, + IN UINT16 f_usDestinationChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_COPY_EVENT pCopyEventEntry; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_COPY_EVENT_ENTRY_PNT( pSharedInfo, pCopyEventEntry, f_usCopyEventIndex ); + + /*=======================================================================*/ + /* Copy the channel's configuration and allocated resources. */ + + /* Save the channel info in the copy event. */ + pCopyEventEntry->usSourceChanIndex = f_usSourceChanIndex; + pCopyEventEntry->bySourcePort = (UINT8)( f_pCopyEventCreate->ulSourcePort & 0xFF ); + + pCopyEventEntry->usDestinationChanIndex = f_usDestinationChanIndex; + pCopyEventEntry->byDestinationPort = (UINT8)( f_pCopyEventCreate->ulDestinationPort & 0xFF ); + + pCopyEventEntry->usMixerEventIndex = f_usMixerEventIndex; + + /*=======================================================================*/ + + /* Form handle returned to user. */ + *f_pCopyEventCreate->pulCopyEventHndl = cOCT6100_HNDL_TAG_COPY_EVENT | (pCopyEventEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_usCopyEventIndex; + + /* Finally, mark the event as used. */ + pCopyEventEntry->fReserved = TRUE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100MixerCopyEventDestroySer + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pCopyEventDestroy Pointer to a destroy copy event structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100MixerCopyEventDestroySer +UINT32 Oct6100MixerCopyEventDestroySer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy ) +{ + UINT16 usCopyEventIndex; + UINT16 usMixerEventIndex; + UINT32 ulResult; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertCopyEventDestroyParams( f_pApiInstance, + f_pCopyEventDestroy, + &usCopyEventIndex, + &usMixerEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the echo cancellation channel. */ + ulResult = Oct6100ApiInvalidateCopyEventStructs( f_pApiInstance, + usCopyEventIndex, + usMixerEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the echo cancellation channel. */ + ulResult = Oct6100ApiReleaseCopyEventResources( f_pApiInstance, + usCopyEventIndex, + usMixerEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Invalidate the handle. */ + f_pCopyEventDestroy->ulCopyEventHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertCopyEventDestroyParams + +Description: + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pCopyEventDestroy Pointer to a destroy copy event structure. +f_pusCopyEventIndex Pointer to the index of the copy event in the API. +f_pusMixerEventIndex Pointer to the index of the copy event in the mixer memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertCopyEventDestroyParams +UINT32 Oct6100ApiAssertCopyEventDestroyParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy, + IN OUT PUINT16 f_pusCopyEventIndex, + IN OUT PUINT16 f_pusMixerEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_COPY_EVENT pCopyEventEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pCopyEventDestroy->ulCopyEventHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_COPY_EVENT ) + return cOCT6100_ERR_MIXER_COPY_EVENT_HANDLE; + + *f_pusCopyEventIndex = (UINT16)( f_pCopyEventDestroy->ulCopyEventHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusCopyEventIndex >= cOCT6100_MAX_MIXER_EVENTS ) + return cOCT6100_ERR_MIXER_COPY_EVENT_HANDLE; + + /*=======================================================================*/ + + mOCT6100_GET_COPY_EVENT_ENTRY_PNT( pSharedInfo, pCopyEventEntry, *f_pusCopyEventIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pCopyEventDestroy->ulCopyEventHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pCopyEventEntry->fReserved != TRUE ) + return cOCT6100_ERR_MIXER_EVENT_NOT_OPEN; + if ( ulEntryOpenCnt != pCopyEventEntry->byEntryOpenCnt ) + return cOCT6100_ERR_MIXER_COPY_EVENT_HANDLE; + + /*=======================================================================*/ + + /* Return the index of the associated event. */ + *f_pusMixerEventIndex = pCopyEventEntry->usMixerEventIndex; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInvalidateCopyEventStructs + +Description: Destroy the link between the two channels. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usCopyEventIndex Index of the copy event in the API. +f_usMixerEventIndex Index of the copy event in the mixer memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInvalidateCopyEventStructs +UINT32 Oct6100ApiInvalidateCopyEventStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usCopyEventIndex, + IN UINT16 f_usMixerEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*=======================================================================*/ + /* Clear the Copy event. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usMixerEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Remove the event from the list. */ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + f_usMixerEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseCopyEventResources + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usCopyEventIndex Index of the copy event in the API. +f_usMixerEventIndex Index of the copy event in the mixer memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseCopyEventResources +UINT32 Oct6100ApiReleaseCopyEventResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usCopyEventIndex, + IN UINT16 f_usMixerEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pDestinationEntry; + tPOCT6100_API_COPY_EVENT pCopyEventEntry; + tPOCT6100_API_MIXER_EVENT pTempEventEntry; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_COPY_EVENT_ENTRY_PNT( pSharedInfo, pCopyEventEntry, f_usCopyEventIndex ); + + ulResult = Oct6100ApiReleaseCopyEventEntry( f_pApiInstance, f_usCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_AC; + + /* Relese the SIN copy event. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, f_usMixerEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_B3; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, f_usMixerEventIndex ); + + /* Invalidate the entry. */ + pTempEventEntry->fReserved = FALSE; + pTempEventEntry->usEventType = cOCT6100_INVALID_INDEX; + pTempEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pDestinationEntry, pCopyEventEntry->usDestinationChanIndex ); + + /* Decrement the copy event count on this channel. */ + pDestinationEntry->usCopyEventCnt--; + + /*=======================================================================*/ + + /* Mark the event entry as unused. */ + pCopyEventEntry->fReserved = FALSE; + pCopyEventEntry->byEntryOpenCnt++; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveMixerEventEntry + +Description: Reserves a free entry in the mixer event list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pusEventIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveMixerEventEntry +UINT32 Oct6100ApiReserveMixerEventEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusEventIndex ) +{ + PVOID pMixerEventAlloc; + UINT32 ulResult; + UINT32 ulEventIndex; + + mOCT6100_GET_MIXER_EVENT_ALLOC_PNT( f_pApiInstance->pSharedInfo, pMixerEventAlloc ) + + ulResult = OctapiLlmAllocAlloc( pMixerEventAlloc, &ulEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_MIXER_ALL_MIXER_EVENT_ENTRY_OPENED; + else + return cOCT6100_ERR_FATAL_2B; + } + + *f_pusEventIndex = (UINT16)( ulEventIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseMixerEventEntry + +Description: Release an entry from the mixer event list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usEventIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseMixerEventEntry +UINT32 Oct6100ApiReleaseMixerEventEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEventIndex ) +{ + PVOID pMixerEventAlloc; + UINT32 ulResult; + + mOCT6100_GET_MIXER_EVENT_ALLOC_PNT( f_pApiInstance->pSharedInfo, pMixerEventAlloc ) + + ulResult = OctapiLlmAllocDealloc( pMixerEventAlloc, f_usEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_2C; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetFreeMixerEventCnt + +Description: Retrieve the number of events left in the list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pulFreeEventCnt How many events left. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetFreeMixerEventCnt +UINT32 Oct6100ApiGetFreeMixerEventCnt( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT32 f_pulFreeEventCnt ) +{ + PVOID pMixerEventAlloc; + UINT32 ulResult; + UINT32 ulAllocatedEvents; + UINT32 ulAvailableEvents; + + mOCT6100_GET_MIXER_EVENT_ALLOC_PNT( f_pApiInstance->pSharedInfo, pMixerEventAlloc ) + + ulResult = OctapiLlmAllocInfo( pMixerEventAlloc, &ulAllocatedEvents, &ulAvailableEvents ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_E8; + + /* Return number of free events. */ + *f_pulFreeEventCnt = ulAvailableEvents; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveCopyEventEntry + +Description: Reserves a free entry in the copy event list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pusEventIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveCopyEventEntry +UINT32 Oct6100ApiReserveCopyEventEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusEventIndex ) +{ + PVOID pCopyEventAlloc; + UINT32 ulResult; + UINT32 ulEventIndex; + + mOCT6100_GET_COPY_EVENT_ALLOC_PNT( f_pApiInstance->pSharedInfo, pCopyEventAlloc ) + + ulResult = OctapiLlmAllocAlloc( pCopyEventAlloc, &ulEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_MIXER_ALL_COPY_EVENT_ENTRY_OPENED; + else + return cOCT6100_ERR_FATAL_AD; + } + + *f_pusEventIndex = (UINT16)( ulEventIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseCopyEventEntry + +Description: Release an entry from the copy event list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usEventIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseCopyEventEntry +UINT32 Oct6100ApiReleaseCopyEventEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEventIndex ) +{ + PVOID pCopyEventAlloc; + UINT32 ulResult; + + mOCT6100_GET_COPY_EVENT_ALLOC_PNT( f_pApiInstance->pSharedInfo, pCopyEventAlloc ) + + ulResult = OctapiLlmAllocDealloc( pCopyEventAlloc, f_usEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_AE; + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_phasing_tsst.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_phasing_tsst.c new file mode 100644 index 0000000..e8a4199 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_phasing_tsst.c @@ -0,0 +1,922 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_phasing_tsst.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains functions used to open and close phasing TSSTs. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 46 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_phasing_tsst_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_phasing_tsst_pub.h" +#include "oct6100api/oct6100_channel_inst.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_tsst_priv.h" +#include "oct6100_phasing_tsst_priv.h" + +/**************************** PUBLIC FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100PhasingTsstOpen + +Description: This function opens a phasing TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pPhasingTsstOpen Pointer to phasing TSST open structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100PhasingTsstOpenDef +UINT32 Oct6100PhasingTsstOpenDef( + tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen ) +{ + f_pPhasingTsstOpen->pulPhasingTsstHndl = NULL; + + f_pPhasingTsstOpen->ulTimeslot = cOCT6100_INVALID_TIMESLOT; + f_pPhasingTsstOpen->ulStream = cOCT6100_INVALID_STREAM; + + f_pPhasingTsstOpen->ulPhasingLength = 88; + + + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100PhasingTsstOpen +UINT32 Oct6100PhasingTsstOpen( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100PhasingTsstOpenSer( f_pApiInstance, f_pPhasingTsstOpen ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100PhasingTsstClose + +Description: This function closes a phasing TSST + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pPhasingTsstClose Pointer to phasing TSST close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100PhasingTsstCloseDef +UINT32 Oct6100PhasingTsstCloseDef( + tPOCT6100_PHASING_TSST_CLOSE f_pPhasingTsstClose ) +{ + f_pPhasingTsstClose->ulPhasingTsstHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100PhasingTsstClose +UINT32 Oct6100PhasingTsstClose( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_PHASING_TSST_CLOSE f_pPhasingTsstClose ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100PhasingTsstCloseSer( f_pApiInstance, f_pPhasingTsstClose ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetPhasingTsstSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of Phasing TSSTs. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pOpenChip Pointer to chip configuration struct. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetPhasingTsstSwSizes +UINT32 Oct6100ApiGetPhasingTsstSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + + /* Determine the amount of memory required for the API phasing TSST list. */ + f_pInstSizes->ulPhasingTsstList = f_pOpenChip->ulMaxPhasingTssts * sizeof( tOCT6100_API_PHASING_TSST ); + + if ( f_pOpenChip->ulMaxPhasingTssts > 0 ) + { + /* Calculate memory needed for Phasing TSST API memory allocation */ + ulResult = OctapiLlmAllocGetSize( f_pOpenChip->ulMaxPhasingTssts, &f_pInstSizes->ulPhasingTsstAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_38; + } + else + { + f_pInstSizes->ulPhasingTsstAlloc = 0; + } + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulPhasingTsstList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulPhasingTsstAlloc, ulTempVar ) + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiPhasingTsstSwInit + +Description: Initializes all elements of the instance structure associated + to phasing TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiPhasingTsstSwInit +UINT32 Oct6100ApiPhasingTsstSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_API_PHASING_TSST pPhasingTsstList; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulMaxPhasingTssts; + PVOID pPhasingTsstAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Initialize the phasing TSST API list. */ + ulMaxPhasingTssts = pSharedInfo->ChipConfig.usMaxPhasingTssts; + + /* Set all entries in the phasing TSST list to unused. */ + mOCT6100_GET_PHASING_TSST_LIST_PNT( pSharedInfo, pPhasingTsstList ) + + /* Clear the memory */ + Oct6100UserMemSet( pPhasingTsstList, 0x00, sizeof(tOCT6100_API_PHASING_TSST) * ulMaxPhasingTssts ); + + /* Initialize the phasing TSST allocation software to "all free". */ + if ( ulMaxPhasingTssts > 0 ) + { + mOCT6100_GET_PHASING_TSST_ALLOC_PNT( pSharedInfo, pPhasingTsstAlloc ) + + ulResult = OctapiLlmAllocInit( &pPhasingTsstAlloc, ulMaxPhasingTssts ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_39; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100PhasingTsstOpenSer + +Description: Opens a phasing TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pPhasingTsstOpen Pointer to phasing TSST open configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100PhasingTsstOpenSer +UINT32 Oct6100PhasingTsstOpenSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen ) +{ + UINT16 usPhasingIndex; + UINT16 usTsstIndex; + UINT32 ulResult; + + /* Check the user's configuration of the phasing TSST for errors. */ + ulResult = Oct6100ApiCheckPhasingParams( f_pApiInstance, f_pPhasingTsstOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the phasing TSST. */ + ulResult = Oct6100ApiReservePhasingResources( f_pApiInstance, f_pPhasingTsstOpen, &usPhasingIndex, &usTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write all necessary structures to activate the phasing TSST. */ + ulResult = Oct6100ApiWritePhasingStructs( f_pApiInstance, f_pPhasingTsstOpen, usPhasingIndex, usTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the new phasing TSST entry in the API list. */ + ulResult = Oct6100ApiUpdatePhasingEntry( f_pApiInstance, f_pPhasingTsstOpen, usPhasingIndex, usTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckPhasingParams + +Description: Checks the user's phasing TSST open configuration for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pPhasingTsstOpen Pointer to phasing TSST open configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckPhasingParams +UINT32 Oct6100ApiCheckPhasingParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen ) +{ + UINT32 ulResult; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxPhasingTssts == 0 ) + return cOCT6100_ERR_PHASING_TSST_DISABLED; + + if ( f_pPhasingTsstOpen->pulPhasingTsstHndl == NULL ) + return cOCT6100_ERR_PHASING_TSST_INVALID_HANDLE; + + /* Check the phasing length. */ + if ( f_pPhasingTsstOpen->ulPhasingLength > 240 || + f_pPhasingTsstOpen->ulPhasingLength < 2 ) + return cOCT6100_ERR_PHASING_TSST_PHASING_LENGTH; + + + + /* Check the input TDM streams, timeslots component for errors. */ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + cOCT6100_NUMBER_TSSTS_1, + f_pPhasingTsstOpen->ulTimeslot, + f_pPhasingTsstOpen->ulStream, + cOCT6100_INPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_PHASING_TSST_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_PHASING_TSST_STREAM; + } + else + { + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReservePhasingResources + +Description: Reserves all resources needed for the new phasing TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pPhasingTsstOpen Pointer to phasing TSST configuration structure. +f_pusPhasingIndex Allocated entry in Phasing TSST API list. +f_pusTsstIndex TSST memory index of the counter. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReservePhasingResources +UINT32 Oct6100ApiReservePhasingResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen, + OUT PUINT16 f_pusPhasingIndex, + OUT PUINT16 f_pusTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + UINT32 ulTempVar; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Reserve an entry in the phasing TSST list. */ + ulResult = Oct6100ApiReservePhasingEntry( f_pApiInstance, + f_pusPhasingIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Reserve the input TSST entry. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + f_pPhasingTsstOpen->ulTimeslot, + f_pPhasingTsstOpen->ulStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_INPUT_TSST, + f_pusTsstIndex, + NULL ); + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Release the previously reserved entries. */ + ulTempVar = Oct6100ApiReleasePhasingEntry( f_pApiInstance, *f_pusPhasingIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + + return ulResult; + } + } + else + { + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWritePhasingStructs + +Description: Performs all the required structure writes to configure the + new phasing TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pPhasingTsstOpen Pointer to phasing TSST configuration structure. +f_usPhasingIndex Allocated entry in phasing TSST API list. +f_usTsstIndex TSST memory index of the counter. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWritePhasingStructs +UINT32 Oct6100ApiWritePhasingStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen, + IN UINT16 f_usPhasingIndex, + IN UINT16 f_usTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulPhasingTsstChariotMemIndex; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*------------------------------------------------------------------------------*/ + /* Configure the TSST control memory of the phasing TSST. */ + + /* Find the asociated entry in the chariot memory for the phasing TSST. */ + ulPhasingTsstChariotMemIndex = cOCT6100_TSST_CONTROL_PHASING_TSST_BASE_ENTRY + f_usPhasingIndex; + + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( f_usTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_TSST_CONTROL_MEM_INPUT_TSST; + WriteParams.usWriteData |= ulPhasingTsstChariotMemIndex & cOCT6100_TSST_CONTROL_MEM_TSI_MEM_MASK; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + /*------------------------------------------------------------------------------*/ + /* Write the phasing length of the TSST in the ADPCM / MIXER memory. */ + + WriteParams.ulWriteAddress = cOCT6100_CONVERSION_CONTROL_PHASE_SIZE_BASE_ADD + ( f_usPhasingIndex * 2 ); + WriteParams.usWriteData = (UINT16)( f_pPhasingTsstOpen->ulPhasingLength ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdatePhasingEntry + +Description: Updates the new phasing TSST in the API phasing TSST list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pPhasingTsstOpen Pointer to phasing TSST open structure. +f_usPhasingIndex Allocated entry in phasing TSST API list. +f_usTsstIndex TSST memory index of the counter. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdatePhasingEntry +UINT32 Oct6100ApiUpdatePhasingEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen, + IN UINT16 f_usPhasingIndex, + IN UINT16 f_usTsstIndex ) +{ + tPOCT6100_API_PHASING_TSST pPhasingTsstEntry; + + /*================================================================================*/ + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPhasingTsstEntry, f_usPhasingIndex ) + + /* Copy the phasing TSST's configuration and allocated resources. */ + pPhasingTsstEntry->usTimeslot = (UINT16)( f_pPhasingTsstOpen->ulTimeslot & 0xFFFF ); + pPhasingTsstEntry->usStream = (UINT16)( f_pPhasingTsstOpen->ulStream & 0xFFFF ); + + pPhasingTsstEntry->usPhasingLength = (UINT16)( f_pPhasingTsstOpen->ulPhasingLength & 0xFFFF ); + + /* Store hardware related information. */ + pPhasingTsstEntry->usPhasingTsstIndex = f_usTsstIndex; + + /* Form handle returned to user. */ + *f_pPhasingTsstOpen->pulPhasingTsstHndl = cOCT6100_HNDL_TAG_PHASING_TSST | (pPhasingTsstEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_usPhasingIndex; + pPhasingTsstEntry->usDependencyCnt = 0; /* Nobody is using the phasing TSST.*/ + + /* Finally, mark the phasing TSST as open. */ + pPhasingTsstEntry->fReserved = TRUE; + + /* Increment the number of phasing TSSTs opened. */ + f_pApiInstance->pSharedInfo->ChipStats.usNumberPhasingTssts++; + + /*================================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100PhasingTsstCloseSer + +Description: Closes a phasing TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pPhasingTsstClose Pointer to phasing TSST close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100PhasingTsstCloseSer +UINT32 Oct6100PhasingTsstCloseSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PHASING_TSST_CLOSE f_pPhasingTsstClose ) +{ + UINT16 usPhasingIndex; + UINT16 usTsstIndex; + UINT32 ulResult; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertPhasingParams( f_pApiInstance, f_pPhasingTsstClose, &usPhasingIndex, &usTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the phasing TSST. */ + ulResult = Oct6100ApiInvalidatePhasingStructs( f_pApiInstance, usTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the phasing TSST. */ + ulResult = Oct6100ApiReleasePhasingResources( f_pApiInstance, usPhasingIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + f_pPhasingTsstClose->ulPhasingTsstHndl = cOCT6100_INVALID_VALUE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertPhasingParams + +Description: Validate the handle given by the user and verify the state of + the phasing TSST about to be closed. Also returns all + required information to deactivate the phasing TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pPhasingTsstClose Pointer to phasing TSST close structure. +f_pusPhasingIndex Index of the phasing TSST structure in the API list. +f_pusTsstIndex Index of the entry in the TSST control memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertPhasingParams +UINT32 Oct6100ApiAssertPhasingParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_PHASING_TSST_CLOSE f_pPhasingTsstClose, + OUT PUINT16 f_pusPhasingIndex, + OUT PUINT16 f_pusTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_PHASING_TSST pPhasingEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pPhasingTsstClose->ulPhasingTsstHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_PHASING_TSST ) + return cOCT6100_ERR_PHASING_TSST_INVALID_HANDLE; + + *f_pusPhasingIndex = (UINT16)( f_pPhasingTsstClose->ulPhasingTsstHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusPhasingIndex >= pSharedInfo->ChipConfig.usMaxPhasingTssts ) + return cOCT6100_ERR_PHASING_TSST_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the phasing TSST's list entry. */ + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( pSharedInfo, pPhasingEntry, *f_pusPhasingIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pPhasingTsstClose->ulPhasingTsstHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pPhasingEntry->fReserved != TRUE ) + return cOCT6100_ERR_PHASING_TSST_NOT_OPEN; + if ( pPhasingEntry->usDependencyCnt != 0 ) + return cOCT6100_ERR_PHASING_TSST_ACTIVE_DEPENDENCIES; + if ( ulEntryOpenCnt != pPhasingEntry->byEntryOpenCnt ) + return cOCT6100_ERR_PHASING_TSST_INVALID_HANDLE; + + /* Return info needed to close the phasing TSST and release all resources. */ + *f_pusTsstIndex = pPhasingEntry->usPhasingTsstIndex; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInvalidatePhasingStructs + +Description: Closes a phasing TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usTsstIndex Index of the entry in the TSST control memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInvalidatePhasingStructs +UINT32 Oct6100ApiInvalidatePhasingStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*------------------------------------------------------------------------------*/ + /* Deactivate the TSST control memory. */ + + /* Set the input TSST control entry to unused. */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( f_usTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = 0x0000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleasePhasingResources + +Description: Release and clear the API entry associated to the phasing TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usPhasingIndex Index of the phasing TSST in the API list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleasePhasingResources +UINT32 Oct6100ApiReleasePhasingResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usPhasingIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_PHASING_TSST pPhasingEntry; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( pSharedInfo, pPhasingEntry, f_usPhasingIndex ); + + /* Release the entry in the phasing TSST list. */ + ulResult = Oct6100ApiReleasePhasingEntry( f_pApiInstance, f_usPhasingIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Release the entry. */ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pPhasingEntry->usTimeslot, + pPhasingEntry->usStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); /* Release the TSST entry */ + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL; + } + } + else + { + return ulResult; + } + + /*=============================================================*/ + /* Update the phasing TSST's list entry. */ + + /* Mark the entry as closed. */ + pPhasingEntry->fReserved = FALSE; + pPhasingEntry->byEntryOpenCnt++; + + /* Decrement the number of phasing TSSTs opened. */ + f_pApiInstance->pSharedInfo->ChipStats.usNumberPhasingTssts--; + + /*=============================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReservePhasingEntry + +Description: Reserves a phasing TSST API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pusPhasingIndex Resulting index reserved in the phasing TSST list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReservePhasingEntry +UINT32 Oct6100ApiReservePhasingEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusPhasingIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pPhasingAlloc; + UINT32 ulResult; + UINT32 ulPhasingIndex; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_PHASING_TSST_ALLOC_PNT( pSharedInfo, pPhasingAlloc ) + + ulResult = OctapiLlmAllocAlloc( pPhasingAlloc, &ulPhasingIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_PHASING_TSST_ALL_ENTRIES_ARE_OPENED; + else + return cOCT6100_ERR_FATAL_3A; + } + + *f_pusPhasingIndex = (UINT16)( ulPhasingIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleasePhasingEntry + +Description: Releases the specified phasing TSST API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usPhasingIndex Index reserved in the phasing TSST API list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleasePhasingEntry +UINT32 Oct6100ApiReleasePhasingEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usPhasingIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pPhasingAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_PHASING_TSST_ALLOC_PNT( pSharedInfo, pPhasingAlloc ) + + ulResult = OctapiLlmAllocDealloc( pPhasingAlloc, f_usPhasingIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_3B; + } + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_playout_buf.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_playout_buf.c new file mode 100644 index 0000000..cf3affa --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_playout_buf.c @@ -0,0 +1,3337 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_playout_buf.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains functions used to manage buffer playout. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 109 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_playout_buf_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_events_pub.h" +#include "oct6100api/oct6100_playout_buf_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_events_priv.h" +#include "oct6100_playout_buf_priv.h" + +/**************************** PUBLIC FUNCTIONS *****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutLoad + +Description: This function loads a playout buffer into external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferLoad Pointer to buffer playout load structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutLoadDef +UINT32 Oct6100BufferPlayoutLoadDef( + tPOCT6100_BUFFER_LOAD f_pBufferLoad ) +{ + f_pBufferLoad->pbyBufferPattern = NULL; + f_pBufferLoad->ulBufferSize = 128; + f_pBufferLoad->ulBufferPcmLaw = cOCT6100_PCM_U_LAW; + + f_pBufferLoad->pulBufferIndex = NULL; + f_pBufferLoad->pulPlayoutFreeMemSize = NULL; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100BufferPlayoutLoad +UINT32 Oct6100BufferPlayoutLoad( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_BUFFER_LOAD f_pBufferLoad ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100BufferLoadSer( f_pApiInstance, f_pBufferLoad, TRUE, cOCT6100_INVALID_INDEX ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutLoadBlockInit + +Description: This function allows the user to initialize loading a buffer + into external memory using blocks. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pBufferLoadBlockInit Pointer to buffer playout load block init structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutLoadBlockInitDef +UINT32 Oct6100BufferPlayoutLoadBlockInitDef( + tPOCT6100_BUFFER_LOAD_BLOCK_INIT f_pBufferLoadBlockInit ) +{ + f_pBufferLoadBlockInit->ulBufferSize = 128; + f_pBufferLoadBlockInit->ulBufferPcmLaw = cOCT6100_PCM_U_LAW; + + f_pBufferLoadBlockInit->pulBufferIndex = NULL; + f_pBufferLoadBlockInit->pulPlayoutFreeMemSize = NULL; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100BufferPlayoutLoadBlockInit +UINT32 Oct6100BufferPlayoutLoadBlockInit( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_BUFFER_LOAD_BLOCK_INIT f_pBufferLoadBlockInit ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100BufferLoadBlockInitSer( f_pApiInstance, f_pBufferLoadBlockInit ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutLoadBlock + +Description: This function allows the user to load a buffer block into + external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pBufferLoadBlock Pointer to buffer playout load block structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutLoadBlockDef +UINT32 Oct6100BufferPlayoutLoadBlockDef( + tPOCT6100_BUFFER_LOAD_BLOCK f_pBufferLoadBlock ) +{ + f_pBufferLoadBlock->ulBufferIndex = cOCT6100_INVALID_VALUE; + f_pBufferLoadBlock->ulBlockLength = cOCT6100_INVALID_VALUE; + f_pBufferLoadBlock->ulBlockOffset = cOCT6100_INVALID_VALUE; + + f_pBufferLoadBlock->pbyBufferPattern = NULL; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100BufferPlayoutLoadBlock +UINT32 Oct6100BufferPlayoutLoadBlock( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_BUFFER_LOAD_BLOCK f_pBufferLoadBlock ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100BufferLoadBlockSer( f_pApiInstance, f_pBufferLoadBlock ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutUnload + +Description: This function unloads a playout buffer from external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferUnload Pointer to buffer playout unload structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutUnloadDef +UINT32 Oct6100BufferPlayoutUnloadDef( + tPOCT6100_BUFFER_UNLOAD f_pBufferUnload ) +{ + f_pBufferUnload->ulBufferIndex = cOCT6100_INVALID_VALUE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100BufferPlayoutUnload +UINT32 Oct6100BufferPlayoutUnload( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_BUFFER_UNLOAD f_pBufferUnload ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100BufferUnloadSer( f_pApiInstance, f_pBufferUnload, TRUE ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutAdd + +Description: This function adds a buffer to a port's playout list on the + selected channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutAdd Pointer to buffer playout add structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutAddDef +UINT32 Oct6100BufferPlayoutAddDef( + tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd ) +{ + f_pBufferPlayoutAdd->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pBufferPlayoutAdd->ulBufferIndex = cOCT6100_INVALID_VALUE; + + f_pBufferPlayoutAdd->ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + f_pBufferPlayoutAdd->ulMixingMode = cOCT6100_MIXING_MINUS_6_DB; + f_pBufferPlayoutAdd->lGainDb = 0; + + f_pBufferPlayoutAdd->fRepeat = FALSE; + f_pBufferPlayoutAdd->ulRepeatCount = cOCT6100_REPEAT_INFINITELY; + + f_pBufferPlayoutAdd->ulDuration = cOCT6100_INVALID_VALUE; + + f_pBufferPlayoutAdd->ulBufferLength = cOCT6100_AUTO_SELECT; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100BufferPlayoutAdd +UINT32 Oct6100BufferPlayoutAdd( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100BufferPlayoutAddSer( f_pApiInstance, f_pBufferPlayoutAdd ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutStart + +Description: This function enables playout of the specified buffer on the + requested channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutStart Pointer to buffer playout start structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutStartDef +UINT32 Oct6100BufferPlayoutStartDef( + tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart ) +{ + f_pBufferPlayoutStart->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pBufferPlayoutStart->ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + f_pBufferPlayoutStart->fNotifyOnPlayoutStop = FALSE; + f_pBufferPlayoutStart->ulUserEventId = cOCT6100_INVALID_VALUE; + f_pBufferPlayoutStart->fAllowStartWhileActive = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100BufferPlayoutStart +UINT32 Oct6100BufferPlayoutStart( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100BufferPlayoutStartSer( f_pApiInstance, f_pBufferPlayoutStart, cOCT6100_BUFFER_PLAYOUT_EVENT_STOP ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutStop + +Description: This function disables playout of a buffer on the specified + channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutStop Pointer to buffer playout stop structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutStopDef +UINT32 Oct6100BufferPlayoutStopDef( + tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop ) +{ + f_pBufferPlayoutStop->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pBufferPlayoutStop->ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + f_pBufferPlayoutStop->fStopCleanly = TRUE; + f_pBufferPlayoutStop->pfAlreadyStopped = NULL; + f_pBufferPlayoutStop->pfNotifyOnPlayoutStop = NULL; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100BufferPlayoutStop +UINT32 Oct6100BufferPlayoutStop( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100BufferPlayoutStopSer( f_pApiInstance, f_pBufferPlayoutStop ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetPlayoutBufferSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of playout buffers. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pOpenChip Pointer to chip configuration struct. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetPlayoutBufferSwSizes +UINT32 Oct6100ApiGetPlayoutBufferSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + + /* Calculate memory needed for playout buffer list. */ + f_pInstSizes->ulPlayoutBufList = f_pOpenChip->ulMaxPlayoutBuffers * sizeof( tOCT6100_API_BUFFER ); + + f_pInstSizes->ulPlayoutBufMemoryNodeList = 0; + + /* Calculate memory needed for playout buffer allocation software. */ + if ( f_pOpenChip->ulMaxPlayoutBuffers > 0 ) + { + ulResult = OctapiLlmAllocGetSize( f_pOpenChip->ulMaxPlayoutBuffers, &f_pInstSizes->ulPlayoutBufAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_3C; + + f_pInstSizes->ulPlayoutBufMemoryNodeList = 2 * f_pOpenChip->ulMaxPlayoutBuffers * sizeof( tOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE ); + } + else + { + f_pInstSizes->ulPlayoutBufAlloc = 0; + } + + /* Calculate memory needed for list and allocation software serialization. */ + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulPlayoutBufList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulPlayoutBufAlloc, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulPlayoutBufMemoryNodeList, ulTempVar ) + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiPlayoutBufferSwInit + +Description: Initializes all elements of the instance structure associated + to playout buffers. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiPlayoutBufferSwInit +UINT32 Oct6100ApiPlayoutBufferSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BUFFER pBufferList; + PVOID pBufferPlayoutAlloc; + UINT32 ulMaxBufferPlayout; + UINT32 ulResult, i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get the maximum number of buffer playout. */ + ulMaxBufferPlayout = pSharedInfo->ChipConfig.usMaxPlayoutBuffers; + + /* Set all entries in the buffer playout list to unused. */ + mOCT6100_GET_BUFFER_LIST_PNT( pSharedInfo, pBufferList ) + + for ( i = 0; i < ulMaxBufferPlayout; i++ ) + { + pBufferList[ i ].fReserved = FALSE; + pBufferList[ i ].ulBufferSize = 0; + pBufferList[ i ].ulBufferBase = cOCT6100_INVALID_VALUE; + pBufferList[ i ].usDependencyCnt = 0; + pBufferList[ i ].byBufferPcmLaw = cOCT6100_PCM_U_LAW; + + } + + /* Initialize the buffer playout allocation software to "all free". */ + if ( ulMaxBufferPlayout > 0 ) + { + mOCT6100_GET_BUFFER_ALLOC_PNT( pSharedInfo, pBufferPlayoutAlloc ) + + ulResult = OctapiLlmAllocInit( &pBufferPlayoutAlloc, ulMaxBufferPlayout ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_3D; + } + + /* Initialize the amount of free memory used by playout. */ + f_pApiInstance->pSharedInfo->ChipStats.ulPlayoutMemUsed = 0; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferLoadSer + +Description: Loads a buffer in external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferLoad Pointer to buffer configuration structure. The handle + identifying the buffer in all future function calls is + returned in this structure. + +f_fReserveListStruct Flag indicating if a list structure should be reserved + or if the structure has been reserved before. If this + is set, the f_ulBufIndex variable must also be set. + +f_ulBufIndex If the f_fReserveListStruct flag is set, this index + will identify the buffer playout list structure + that must be used to load the specified buffer. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferLoadSer +UINT32 Oct6100BufferLoadSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD f_pBufferLoad, + IN BOOL f_fReserveListStruct, + IN UINT32 f_ulBufIndex ) +{ + UINT32 ulBufferIndex; + UINT32 ulBufferBase; + UINT32 ulResult; + + /* Check the user's configuration of the buffer for errors. */ + ulResult = Oct6100ApiCheckBufferParams( f_pApiInstance, f_pBufferLoad, TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the buffer. */ + ulResult = Oct6100ApiReserveBufferResources( f_pApiInstance, f_pBufferLoad, f_fReserveListStruct, f_ulBufIndex, &ulBufferIndex, &ulBufferBase ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write the buffer in external memory. */ + ulResult = Oct6100ApiWriteBufferInMemory( f_pApiInstance, ulBufferBase, f_pBufferLoad->ulBufferSize, f_pBufferLoad->pbyBufferPattern ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the new buffer's entry in the buffer list. */ + ulResult = Oct6100ApiUpdateBufferEntry( f_pApiInstance, f_pBufferLoad, ulBufferIndex, ulBufferBase ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferLoadBlockInitSer + +Description: Reserve resources for loading a buffer into external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pBufferLoadBlockInit Pointer to buffer configuration structure. The + handle identifying the buffer in all future + function calls is returned in this structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferLoadBlockInitSer +UINT32 Oct6100BufferLoadBlockInitSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD_BLOCK_INIT f_pBufferLoadBlockInit ) +{ + UINT32 ulBufferIndex; + UINT32 ulBufferBase; + UINT32 ulResult; + tOCT6100_BUFFER_LOAD BufferLoad; + + Oct6100BufferPlayoutLoadDef( &BufferLoad ); + + /* Not to replicate the code, we use the BufferLoad functions directly. */ + BufferLoad.pulBufferIndex = f_pBufferLoadBlockInit->pulBufferIndex; + BufferLoad.pulPlayoutFreeMemSize = f_pBufferLoadBlockInit->pulPlayoutFreeMemSize; + BufferLoad.ulBufferPcmLaw = f_pBufferLoadBlockInit->ulBufferPcmLaw; + BufferLoad.ulBufferSize = f_pBufferLoadBlockInit->ulBufferSize; + BufferLoad.pbyBufferPattern = NULL; /* Must not check this for now */ + + /* Check the user's configuration of the buffer for errors, but do */ + /* not check if the buffer pointer is NULL. It is NULL for sure! */ + ulResult = Oct6100ApiCheckBufferParams( f_pApiInstance, &BufferLoad, FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the buffer. */ + ulResult = Oct6100ApiReserveBufferResources( f_pApiInstance, &BufferLoad, TRUE, cOCT6100_INVALID_INDEX, &ulBufferIndex, &ulBufferBase ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the new buffer's entry in the buffer list. */ + ulResult = Oct6100ApiUpdateBufferEntry( f_pApiInstance, &BufferLoad, ulBufferIndex, ulBufferBase ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferLoadBlockSer + +Description: Loads a buffer in external memory using blocks. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pBufferLoadBlock Pointer to buffer block to be loaded into external + memory descriptor. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferLoadBlockSer +UINT32 Oct6100BufferLoadBlockSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD_BLOCK f_pBufferLoadBlock ) +{ + UINT32 ulBufferBase; + UINT32 ulResult; + + /* Check the user's configuration for errors. */ + ulResult = Oct6100ApiCheckBufferLoadBlockParams( f_pApiInstance, f_pBufferLoadBlock, &ulBufferBase ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write the buffer in external memory at the appropriate offset - must do some pointer arithmetic. */ + ulResult = Oct6100ApiWriteBufferInMemory( f_pApiInstance, ulBufferBase + f_pBufferLoadBlock->ulBlockOffset, + f_pBufferLoadBlock->ulBlockLength, f_pBufferLoadBlock->pbyBufferPattern + f_pBufferLoadBlock->ulBlockOffset ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckBufferParams + +Description: Checks the user's buffer playout load configuration for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferLoad Pointer to buffer configuration structure. +f_fCheckBufferPtr Check if the buffer pointer is NULL or not. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckBufferParams +UINT32 Oct6100ApiCheckBufferParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD f_pBufferLoad, + IN BOOL f_fCheckBufferPtr ) +{ + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxPlayoutBuffers == 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_DISABLED; + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fBufferPlayout == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_BUFFER_PLAYOUT; + + if ( f_pBufferLoad->pulBufferIndex == NULL ) + return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_INDEX; + + if( f_fCheckBufferPtr ) + { + if ( f_pBufferLoad->pbyBufferPattern == NULL ) + return cOCT6100_ERR_BUFFER_PLAYOUT_PATTERN; + } + + if ( f_pBufferLoad->ulBufferSize < cOCT6100_MINIMUM_BUFFER_SIZE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_TOO_SMALL; + + if ( ( f_pBufferLoad->ulBufferSize % cOCT6100_BUFFER_SIZE_GRANULARITY ) != 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_SIZE; + + if ( f_pBufferLoad->ulBufferPcmLaw != cOCT6100_PCM_U_LAW && + f_pBufferLoad->ulBufferPcmLaw != cOCT6100_PCM_A_LAW ) + return cOCT6100_ERR_BUFFER_PLAYOUT_PCM_LAW; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckBufferLoadBlockParams + +Description: Checks the user's buffer playout load block configuration for + errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferLoadBlock Pointer to buffer block descriptor. +f_pulBufferBase Pointer to the base address of the buffer in external + memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckBufferLoadBlockParams +UINT32 Oct6100ApiCheckBufferLoadBlockParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_LOAD_BLOCK f_pBufferLoadBlock, + OUT PUINT32 f_pulBufferBase ) +{ + /* Check for errors. */ + tPOCT6100_API_BUFFER pBufEntry; + + if ( f_pBufferLoadBlock->ulBufferIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxPlayoutBuffers ) + return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_INDEX; + + mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBufEntry, f_pBufferLoadBlock->ulBufferIndex ) + + if ( pBufEntry->fReserved != TRUE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_NOT_OPEN; + + if ( ( f_pBufferLoadBlock->ulBlockLength % 2 ) != 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_BLOCK_LENGTH_INVALID; + + if ( ( f_pBufferLoadBlock->ulBlockOffset % 2 ) != 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_BLOCK_OFFSET_INVALID; + + if ( f_pBufferLoadBlock->pbyBufferPattern == NULL ) + return cOCT6100_ERR_BUFFER_PLAYOUT_PATTERN; + + /* Check boundaries */ + if ( ( f_pBufferLoadBlock->ulBlockLength + f_pBufferLoadBlock->ulBlockOffset ) > pBufEntry->ulBufferSize ) + return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_SIZE; + + *f_pulBufferBase = pBufEntry->ulBufferBase; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveBufferResources + +Description: Reserves all resources needed for the new buffer. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferLoad Pointer to buffer configuration structure. + +f_fReserveListStruct Flag indicating if a list structure should be reserved + or if the structure has been reserved before. + +f_ulBufIndex If the f_fReserveListStruct flag is set, this index + will identifying the buffer playout list structure + that must be used to load the specified buffer. + +f_pulBufferIndex Allocated entry in buffer playout list. + +f_pulBufferBase Allocated external memory block for the buffer. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveBufferResources +UINT32 Oct6100ApiReserveBufferResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_LOAD f_pBufferLoad, + IN BOOL f_fReserveListStruct, + IN UINT32 f_ulBufIndex, + OUT PUINT32 f_pulBufferIndex, + OUT PUINT32 f_pulBufferBase ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult = cOCT6100_ERR_OK; + UINT32 ulTempVar; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Reserve an entry in the buffer list. */ + if ( f_fReserveListStruct == TRUE ) + { + ulResult = Oct6100ApiReserveBufPlayoutListEntry( f_pApiInstance, f_pulBufferIndex ); + } + else + { + *f_pulBufferIndex = f_ulBufIndex; + } + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Find a free block to store the buffer. */ + ulResult = Oct6100ApiReserveBufferPlayoutMemory( f_pApiInstance, f_pBufferLoad->ulBufferSize, f_pulBufferBase ); + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Release the list entry. */ + if ( f_fReserveListStruct == TRUE ) + { + ulTempVar = Oct6100ApiReleaseBufPlayoutListEntry( f_pApiInstance, *f_pulBufferIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + } + } + + return ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteBufferInMemory + +Description: Writes the buffer in external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulBufferBase Allocated external memory address for the buffer. + +f_ulBufferLength Length in bytes of the buffer to be copied in memory. + +f_pbyBuffer Address where the buffer should be copied from. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteBufferInMemory +UINT32 Oct6100ApiWriteBufferInMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulBufferBase, + IN UINT32 f_ulBufferLength, + IN PUINT8 f_pbyBuffer ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_BURST_PARAMS BurstParams; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + UINT32 ulNumWrites; + PUINT16 pusSuperArray; + PUINT8 pbyPlayoutBuffer; + UINT32 ulByteCount = 0; + UINT32 i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Write the buffer in external memory. */ + ulNumWrites = f_ulBufferLength / 2; + + BurstParams.ulWriteAddress = f_ulBufferBase; + BurstParams.pusWriteData = pSharedInfo->MiscVars.ausSuperArray; + + pusSuperArray = pSharedInfo->MiscVars.ausSuperArray; + pbyPlayoutBuffer = f_pbyBuffer; + + /* Check if we can maximize the bandwidth through the CPU port. */ + if ( f_pApiInstance->pSharedInfo->ChipStats.usNumberChannels == 0 ) + { + WriteParams.ulWriteAddress = 0x234; + WriteParams.usWriteData = 0x08ff; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + while ( ulNumWrites != 0 ) + { + if ( ulNumWrites >= pSharedInfo->ChipConfig.usMaxRwAccesses ) + BurstParams.ulWriteLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + else + BurstParams.ulWriteLength = ulNumWrites; + + for ( i = 0; i < BurstParams.ulWriteLength; i++ ) + { + pusSuperArray[ i ] = ( UINT16 )(( pbyPlayoutBuffer [ ulByteCount++ ]) << 8); + pusSuperArray[ i ] |= ( UINT16 )pbyPlayoutBuffer [ ulByteCount++ ]; + } + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + BurstParams.ulWriteAddress += 2 * BurstParams.ulWriteLength; + ulNumWrites -= BurstParams.ulWriteLength; + + } + + /* Make sure we revert back the changes made to the CPU bandwidth register. */ + if ( f_pApiInstance->pSharedInfo->ChipStats.usNumberChannels == 0 ) + { + WriteParams.ulWriteAddress = 0x234; + WriteParams.usWriteData = 0x0804; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateBufferEntry + +Description: Updates the new buffer's entry in the buffer playout list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pBufferLoad Pointer to buffer configuration structure. +f_ulBufferIndex Allocated entry in buffer playout list. +f_ulBufferBase Allocated external memory block for the buffer. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateBufferEntry +UINT32 Oct6100ApiUpdateBufferEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD f_pBufferLoad, + IN UINT32 f_ulBufferIndex, + IN UINT32 f_ulBufferBase ) +{ + tPOCT6100_API_BUFFER pBufEntry; + UINT32 ulBufferSize = f_pBufferLoad->ulBufferSize; + + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBufEntry, f_ulBufferIndex ) + + /* Copy the buffer's configuration and allocated resources. */ + pBufEntry->ulBufferSize = f_pBufferLoad->ulBufferSize; + pBufEntry->byBufferPcmLaw = (UINT8)( f_pBufferLoad->ulBufferPcmLaw & 0xFF ); + pBufEntry->ulBufferBase = f_ulBufferBase; + + /* Update the entries flags. */ + pBufEntry->usDependencyCnt = 0; + + /* Mark the buffer as opened. */ + pBufEntry->fReserved = TRUE; + + /* Increment the number of buffer loaded into the chip.*/ + f_pApiInstance->pSharedInfo->ChipStats.usNumberPlayoutBuffers++; + + /* Refresh the amount of memory used by buffer playout. */ + + /* Reserved size is divisible by 64. */ + if ( ulBufferSize % 64 ) + ulBufferSize = ulBufferSize + ( 64 - ( ulBufferSize % 64 ) ); + f_pApiInstance->pSharedInfo->ChipStats.ulPlayoutMemUsed += ulBufferSize; + + /* Return the buffer index to the user. */ + *f_pBufferLoad->pulBufferIndex = f_ulBufferIndex; + + /* Return the amount of free memory left in the chip. */ + /* Note that this value does not give the "fragmentation" state of the available memory. */ + /* This value only gives the amount of free memory */ + if( f_pBufferLoad->pulPlayoutFreeMemSize ) + *f_pBufferLoad->pulPlayoutFreeMemSize = ( f_pApiInstance->pSharedInfo->MiscVars.ulTotalMemSize - ( f_pApiInstance->pSharedInfo->MemoryMap.ulFreeMemBaseAddress - cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) ) - ( f_pApiInstance->pSharedInfo->ChipStats.ulPlayoutMemUsed ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferUnloadSer + +Description: Unloads a buffer from external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferUnload Pointer to buffer unload structure. +f_fReleaseListStruct Whether to release the buffer playout list structure + or not. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferUnloadSer +UINT32 Oct6100BufferUnloadSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_UNLOAD f_pBufferUnload, + IN BOOL f_fReleaseListStruct ) +{ + UINT32 ulBufferIndex; + UINT32 ulBufferBase; + UINT32 ulResult; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertBufferParams( f_pApiInstance, f_pBufferUnload, &ulBufferIndex, &ulBufferBase ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the unloaded buffer. */ + ulResult = Oct6100ApiReleaseBufferResources( f_pApiInstance, ulBufferIndex, ulBufferBase, f_fReleaseListStruct ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertBufferParams + +Description: Checks the buffer playout unload configuration for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferUnload Pointer to buffer unload structure. +f_pulBufferIndex Pointer to the index of the buffer in the API's buffers list. +f_pulBufferBase Pointer to the base address of the buffer in external memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertBufferParams +UINT32 Oct6100ApiAssertBufferParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_UNLOAD f_pBufferUnload, + OUT PUINT32 f_pulBufferIndex, + OUT PUINT32 f_pulBufferBase ) +{ + tPOCT6100_API_BUFFER pBufEntry; + + *f_pulBufferIndex = f_pBufferUnload->ulBufferIndex; + + if ( *f_pulBufferIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxPlayoutBuffers ) + return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_INDEX; + + mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBufEntry, *f_pulBufferIndex ) + + /* Check for errors. */ + if ( pBufEntry->fReserved != TRUE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_NOT_OPEN; + if ( pBufEntry->usDependencyCnt != 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_ACTIVE_DEPENDENCIES; + + /* Return all info needed to invalidate buffer. */ + *f_pulBufferBase = pBufEntry->ulBufferBase; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseBufferResources + +Description: Release resources needed by the buffer. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulBufferIndex Allocated entry in buffer playout list. +f_ulBufferBase Allocated external memory block for the buffer. +f_fReleaseListStruct Free the list structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseBufferResources +UINT32 Oct6100ApiReleaseBufferResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulBufferIndex, + IN UINT32 f_ulBufferBase, + IN BOOL f_fReleaseListStruct ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BUFFER pBufEntry; + UINT32 ulResult; + UINT32 ulBufferSize; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Free the external memory reserved for the buffer. */ + ulResult = Oct6100ApiReleaseBufferPlayoutMemory( f_pApiInstance, f_ulBufferBase ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_3E; + + /* Release the entry from the buffer list. */ + if ( f_fReleaseListStruct == TRUE ) + ulResult = Oct6100ApiReleaseBufPlayoutListEntry( f_pApiInstance, f_ulBufferIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBufEntry, f_ulBufferIndex ); + + /* Save buffer size before releasing that entry, will be needed to calculate the amount of */ + /* free memory left for the user. */ + ulBufferSize = pBufEntry->ulBufferSize; + + /* Flag the buffer entry as free. */ + pBufEntry->fReserved = FALSE; + + /* Decrement the number of buffer loaded into the chip. */ + f_pApiInstance->pSharedInfo->ChipStats.usNumberPlayoutBuffers--; + + /* Refresh the amount of memory used by buffer playout. */ + /* Reserved size is divisible by 64. */ + if ( ulBufferSize % 64 ) + ulBufferSize = ulBufferSize + ( 64 - ( ulBufferSize % 64 ) ); + f_pApiInstance->pSharedInfo->ChipStats.ulPlayoutMemUsed -= ulBufferSize; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutAddSer + +Description: This function adds a buffer to a channel buffer list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutAdd Pointer to buffer playout add structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutAddSer +UINT32 Oct6100BufferPlayoutAddSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd ) +{ + UINT32 ulBufferIndex; + UINT32 ulChannelIndex; + UINT32 ulResult; + + /* Check the user's configuration of the buffer for errors. */ + ulResult = Oct6100ApiCheckPlayoutAddParams( f_pApiInstance, f_pBufferPlayoutAdd, &ulChannelIndex, &ulBufferIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write to all resources needed to activate buffer playout. */ + ulResult = Oct6100ApiWriteBufferAddStructs( f_pApiInstance, f_pBufferPlayoutAdd, ulChannelIndex, ulBufferIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckPlayoutAddParams + +Description: Check the validity of the channel and buffer requested. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutAdd Pointer to buffer playout add structure. +f_pulChannelIndex Pointer to the channel index of the selected channel. +f_pulBufferIndex Pointer to the buffer index within the API's buffer list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckPlayoutAddParams +UINT32 Oct6100ApiCheckPlayoutAddParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd, + OUT PUINT32 f_pulChannelIndex, + OUT PUINT32 f_pulBufferIndex ) +{ + tPOCT6100_API_BUFFER pBufferEntry; + tPOCT6100_API_CHANNEL pEchoChannel; + UINT32 ulEntryOpenCnt; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxPlayoutBuffers == 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_DISABLED; + + if ( f_pBufferPlayoutAdd->ulChannelHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + if ( f_pBufferPlayoutAdd->ulPlayoutPort != cOCT6100_CHANNEL_PORT_ROUT && + f_pBufferPlayoutAdd->ulPlayoutPort != cOCT6100_CHANNEL_PORT_SOUT ) + return cOCT6100_ERR_BUFFER_PLAYOUT_PLAYOUT_PORT; + + if ( f_pBufferPlayoutAdd->fRepeat != TRUE && f_pBufferPlayoutAdd->fRepeat != FALSE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_ADD_REPEAT; + + if ( f_pBufferPlayoutAdd->fRepeat == TRUE ) + { + if ( f_pBufferPlayoutAdd->ulRepeatCount != cOCT6100_REPEAT_INFINITELY ) + { + if ( f_pBufferPlayoutAdd->ulRepeatCount == 0x0 + || f_pBufferPlayoutAdd->ulRepeatCount > cOCT6100_REPEAT_MAX) + { + return cOCT6100_ERR_BUFFER_PLAYOUT_ADD_REPEAT_COUNT; + } + } + } + + if ( f_pBufferPlayoutAdd->ulMixingMode != cOCT6100_MIXING_0_DB && + f_pBufferPlayoutAdd->ulMixingMode != cOCT6100_MIXING_MINUS_6_DB && + f_pBufferPlayoutAdd->ulMixingMode != cOCT6100_MIXING_MINUS_12_DB && + f_pBufferPlayoutAdd->ulMixingMode != cOCT6100_MIXING_MUTE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_ADD_MIXING; + + if ( ( f_pBufferPlayoutAdd->lGainDb < -24 ) + || ( f_pBufferPlayoutAdd->lGainDb > 24 ) ) + return cOCT6100_ERR_BUFFER_PLAYOUT_ADD_GAIN_DB; + + /*=====================================================================*/ + /* Check the channel handle. */ + + if ( (f_pBufferPlayoutAdd->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + *f_pulChannelIndex = f_pBufferPlayoutAdd->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK; + if ( *f_pulChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChannel, *f_pulChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pBufferPlayoutAdd->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChannel->fReserved != TRUE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChannel->byEntryOpenCnt ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + /* Check if repeat flag has been used for this port. */ + if ( ( ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) && ( pEchoChannel->fRinBufPlayoutRepeatUsed == TRUE ) ) + || ( ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) && ( pEchoChannel->fSoutBufPlayoutRepeatUsed == TRUE ) ) ) + return cOCT6100_ERR_BUFFER_PLAYOUT_REPEAT_USED; + + /*=====================================================================*/ + + /*=====================================================================*/ + /* Check the buffer information. */ + + *f_pulBufferIndex = f_pBufferPlayoutAdd->ulBufferIndex; + if ( *f_pulBufferIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxPlayoutBuffers ) + return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_INDEX; + + mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBufferEntry, *f_pulBufferIndex ) + + if ( pBufferEntry->fReserved != TRUE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_NOT_OPEN; + + /* Check if the play length is not larger then the currently uploaded buffer. */ + if ( ( f_pBufferPlayoutAdd->ulBufferLength > pBufferEntry->ulBufferSize ) && + ( f_pBufferPlayoutAdd->ulBufferLength != cOCT6100_AUTO_SELECT ) ) + return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_SIZE; + + if( f_pBufferPlayoutAdd->ulBufferLength != cOCT6100_AUTO_SELECT ) + { + if ( f_pBufferPlayoutAdd->ulBufferLength < cOCT6100_MINIMUM_BUFFER_SIZE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_TOO_SMALL; + + if ( ( f_pBufferPlayoutAdd->ulBufferLength % cOCT6100_BUFFER_SIZE_GRANULARITY ) != 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_SIZE; + } + + /*=====================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteBufferAddStructs + +Description: Write the buffer playout event in the channel's port playout + circular buffer. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutAdd Pointer to buffer playout add structure. +f_ulChannelIndex Index of the channel on which the buffer is to be added. +f_ulBufferIndex Index of the buffer structure within the API's buffer list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteBufferAddStructs +UINT32 Oct6100ApiWriteBufferAddStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulBufferIndex ) +{ + tPOCT6100_API_BUFFER pBufferEntry; + tPOCT6100_API_CHANNEL pEchoChannel; + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT32 ulTempData; + UINT32 ulEventBuffer; + + UINT32 ulReadPtrBytesOfst; + UINT32 ulReadPtrBitOfst; + UINT32 ulReadPtrFieldSize; + + UINT32 ulWritePtrBytesOfst; + UINT32 ulWritePtrBitOfst; + UINT32 ulWritePtrFieldSize; + + UINT32 ulWritePtr; + UINT32 ulReadPtr; + + UINT32 ulPlayoutBaseAddress; + UINT32 ulAddress; + UINT32 ulEventIndex; + UINT32 ulMask; + + UINT32 ulRepeatCount = 0; + BOOL fRepeatCountSet = FALSE; + UINT32 ulDurationModulo = 0; + UINT32 ulEventsToCreate = 1; + UINT32 ulBufferDurationMs; + + UINT32 ulBufferLength; + UINT16 usTempData = 0; + + UINT16 usReadData; + UINT32 ulChipWritePtr; + UINT32 ulReadData; + UINT32 ulLoopCnt = 0; + BOOL fStillPlaying = TRUE; + BOOL fCheckHardStop = FALSE; + BOOL fOldBufferPlayoutVersion = FALSE; + + UINT32 aulWaitTime[ 2 ]; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChannel, f_ulChannelIndex ); + mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBufferEntry, f_ulBufferIndex ); + + /* Select the buffer of interest. */ + if ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + ulEventBuffer = pSharedInfo->MemoryMap.ulChanMainRinPlayoutMemOfst; + ulWritePtr = pEchoChannel->ulRinBufWritePtr; + + ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.usDwordOffset * 4; + ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byBitOffset; + ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byFieldSize; + + ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.usDwordOffset * 4; + ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byBitOffset; + ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byFieldSize; + } + else /* f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + ulEventBuffer = pSharedInfo->MemoryMap.ulChanMainSoutPlayoutMemOfst; + ulWritePtr = pEchoChannel->ulSoutBufWritePtr; + + ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.usDwordOffset * 4; + ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byBitOffset; + ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byFieldSize; + + ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.usDwordOffset * 4; + ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byBitOffset; + ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byFieldSize; + } + + /*=======================================================================*/ + /* Calculate the repeat count. */ + + /* The buffer length is either the total buffer size or the value specified by the user */ + if ( f_pBufferPlayoutAdd->ulBufferLength == cOCT6100_AUTO_SELECT ) + { + ulBufferLength = pBufferEntry->ulBufferSize; + } + else + { + ulBufferLength = f_pBufferPlayoutAdd->ulBufferLength; + } + + if ( f_pBufferPlayoutAdd->ulDuration != cOCT6100_INVALID_VALUE ) + { + /* With duration and buffer length, we can find the number of times we must repeat playing this buffer. */ + ulBufferDurationMs = ulBufferLength / cOCT6100_SAMPLES_PER_MS; + ulRepeatCount = f_pBufferPlayoutAdd->ulDuration / ulBufferDurationMs; + fRepeatCountSet = TRUE; + + /* Check if buffer is larger then asked duration. */ + if ( ulRepeatCount != 0x0 ) + { + /* We might have to create more then 1 event to accomodate for the repeat-max limit. */ + ulEventsToCreate = ( ulRepeatCount / cOCT6100_REPEAT_MAX ) + 1; + } + else + { + /* No repeat event. Maybe only the duration modulo! */ + ulEventsToCreate = 0x0; + } + + /* Check if must create a second event for a buffer that cannot be played completely. */ + ulDurationModulo = f_pBufferPlayoutAdd->ulDuration % ulBufferDurationMs; + if ( ulDurationModulo != 0x0 ) + { + ulDurationModulo *= cOCT6100_SAMPLES_PER_MS; + if ( ulDurationModulo / cOCT6100_BUFFER_SIZE_GRANULARITY ) + { + /* Round the modulo to be on a buffer size granularity. */ + /* This will round down. */ + ulDurationModulo = ( ulDurationModulo / cOCT6100_BUFFER_SIZE_GRANULARITY ) * cOCT6100_BUFFER_SIZE_GRANULARITY; + + /* If the event about to be created is smaller then the minimum buffer size, */ + /* round up to the minimum required by the hardware. */ + if ( ulDurationModulo < cOCT6100_MINIMUM_BUFFER_SIZE ) + ulDurationModulo = cOCT6100_MINIMUM_BUFFER_SIZE; + ulEventsToCreate++; + } + else + { + /* The modulo is too small to be played. Skip. */ + ulDurationModulo = 0; + } + } + } + else if ( f_pBufferPlayoutAdd->fRepeat == TRUE + && f_pBufferPlayoutAdd->ulRepeatCount != cOCT6100_REPEAT_INFINITELY ) + { + /* The repeat count is set directly from the user. */ + ulRepeatCount = f_pBufferPlayoutAdd->ulRepeatCount; + fRepeatCountSet = TRUE; + } + + /*=======================================================================*/ + + /* Set the playout feature base address. */ + ulPlayoutBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_ulChannelIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + + /* Read the read pointer. */ + ulAddress = ulPlayoutBaseAddress + ulReadPtrBytesOfst; + + /* Must read in memory directly since this value is changed by hardware. */ + ulResult = Oct6100ApiReadDword( f_pApiInstance, ulAddress, &ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulReadPtrFieldSize, ulReadPtrBitOfst, &ulMask ); + + /* Store the read pointer. */ + ulReadPtr = ( ulTempData & ulMask ) >> ulReadPtrBitOfst; + + /* Compare the pointers... Are they different? If so, there is something already in the list. */ + if ( ulReadPtr != ulWritePtr ) + { + /* Check if there is enough room for the playout events. */ + if ( ( pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip == TRUE ) + && ( pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip == TRUE ) ) + { + /* 127 or 31 events image. */ + if ( (UINT8)( ( ulWritePtr - ulReadPtr ) & ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - 1 ) ) >= ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - (UINT8)ulEventsToCreate ) ) + fCheckHardStop = TRUE; + } + else + { + /* Old 31 events image. */ + if ( ( ( ulWritePtr - ulReadPtr ) & 0x1F ) >= ( 0x20 - ulEventsToCreate ) ) + fCheckHardStop = TRUE; + + fOldBufferPlayoutVersion = TRUE; + } + + if ( fCheckHardStop == TRUE ) + { + /* Ok. From what was read, the list is full. But we might still have a chance if the hard-stop */ + /* version was used. In this case, some of the buffers in the list might */ + /* become free in a couple of milliseconds, so try to wait for this. */ + + if ( ( ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) && ( pEchoChannel->fRinHardStop == TRUE ) ) + || ( ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) && ( pEchoChannel->fSoutHardStop == TRUE ) ) ) + { + /* Read the 'chip' write pointer in the hardware. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + ReadParams.ulReadAddress = ulPlayoutBaseAddress + ulReadPtrBytesOfst; + + /* Get the write pointer in the chip. */ + ulAddress = ulPlayoutBaseAddress + ulWritePtrBytesOfst; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, pEchoChannel, ulAddress, &ulReadData, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulWritePtrFieldSize, ulWritePtrBitOfst, &ulMask ); + + /* Store the write pointer. */ + ulChipWritePtr = ( ulReadData & ulMask ) >> ulWritePtrBitOfst; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulReadPtrBitOfst < 16 ) + ReadParams.ulReadAddress += 2; + + while( fStillPlaying == TRUE ) + { + /* Read the read pointer until equals to the write pointer. */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulReadPtrBitOfst < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + mOCT6100_CREATE_FEATURE_MASK( ulReadPtrFieldSize, ulReadPtrBitOfst, &ulMask ); + + /* Store the read pointer.*/ + ulReadPtr = ( ulTempData & ulMask ) >> ulReadPtrBitOfst; + + /* Playout has finished when the read pointer reaches the write pointer. */ + if ( ulReadPtr == ulChipWritePtr ) + break; + + ulLoopCnt++; + if ( ulLoopCnt > cOCT6100_MAX_LOOP ) + { + return cOCT6100_ERR_FATAL_E7; + } + + aulWaitTime[ 0 ] = 100; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Clear hard-stop flag. */ + if ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + /* No hard stop for now. */ + pEchoChannel->fRinHardStop = FALSE; + } + else /* if ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) */ + { + /* No hard stop for now. */ + pEchoChannel->fSoutHardStop = FALSE; + } + + /* Now check again if the event can be added... */ + if ( fOldBufferPlayoutVersion == FALSE ) + { + if ( (UINT8)( ( ulWritePtr - ulReadPtr ) & ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - 1 ) ) >= ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - (UINT8)ulEventsToCreate ) ) + return cOCT6100_ERR_BUFFER_PLAYOUT_ADD_EVENT_BUF_FULL; + } + else /* if ( fOldBufferPlayoutVersion == TRUE ) */ + { + /* Old 31 events image. */ + if ( ( ( ulWritePtr - ulReadPtr ) & 0x1F ) >= ( 0x20 - ulEventsToCreate ) ) + return cOCT6100_ERR_BUFFER_PLAYOUT_ADD_EVENT_BUF_FULL; + } + + /* Good, at least another buffer can be added! Add the buffer to the list. */ + } + else + { + /* Well the list is full! */ + return cOCT6100_ERR_BUFFER_PLAYOUT_ADD_EVENT_BUF_FULL; + } + } + } + + /*=======================================================================*/ + /* Write the events. */ + + for ( ulEventIndex = 0; ulEventIndex < ulEventsToCreate; ulEventIndex ++ ) + { + /* Set the playout event base address. */ + if ( ( pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip == TRUE ) + && ( pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip == TRUE ) ) + { + /* 127 or 31 events image. */ + ulAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + (f_ulChannelIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + ulEventBuffer + (cOCT6100_PLAYOUT_EVENT_MEM_SIZE * (ulWritePtr & ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - 1 ))); + } + else + { + /* Old 31 events image. */ + ulAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + (f_ulChannelIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + ulEventBuffer + (cOCT6100_PLAYOUT_EVENT_MEM_SIZE * (ulWritePtr & 0x1F)); + } + + /* EVENT BASE + 0 */ + /* Make sure the xIS and xHS bits are cleared. */ + ulTempData = 0; + + /* Set the repeat count. */ + if ( fRepeatCountSet == TRUE ) + { + if ( ( ulRepeatCount != 0x0 ) && ( ulRepeatCount <= cOCT6100_REPEAT_MAX ) ) + { + /* Use repeat count directly. */ + ulTempData |= ulRepeatCount; + + /* Will be used later when creating the duration modulo event. */ + ulRepeatCount = 0; + } + else if ( ulRepeatCount != 0x0 ) + { + /* Get ready for next event. */ + ulRepeatCount -= cOCT6100_REPEAT_MAX; + + /* Set maximum for this event. */ + ulTempData |= cOCT6100_REPEAT_MAX; + } + else + { + /* Duration modulo case. Nothing to set here. */ + } + } + else /* if ( fRepeatCountSet != TRUE ) */ + { + /* Repeat only once. */ + ulTempData |= 0x1; + } + + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulAddress, ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* EVENT BASE + 4 */ + /* Set the buffer base address and playout configuration. */ + ulAddress += 4; + ulTempData = pBufferEntry->ulBufferBase & 0x07FFFFFF; + + /* Set play indefinitely or loop N times. */ + if ( ( fRepeatCountSet == FALSE ) && ( f_pBufferPlayoutAdd->fRepeat == TRUE ) ) + { + /* Repeat indefinitely. */ + ulTempData |= 0x1 << cOCT6100_PLAYOUT_EVENT_REPEAT_OFFSET; + + if ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + pEchoChannel->fRinBufPlayoutRepeatUsed = TRUE; + else /* if ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) */ + pEchoChannel->fSoutBufPlayoutRepeatUsed = TRUE; + } + + /* Use loop N times feature. */ + ulTempData |= 0x1 << cOCT6100_PLAYOUT_EVENT_LOOP_TIMES_OFFSET; + + /* Set the law.*/ + ulTempData |= ( pBufferEntry->byBufferPcmLaw << cOCT6100_PLAYOUT_EVENT_LAW_OFFSET ); + + /* Set the mixing configuration.*/ + ulTempData |= f_pBufferPlayoutAdd->ulMixingMode << cOCT6100_PLAYOUT_EVENT_MIX_OFFSET; + + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulAddress, ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + /* EVENT BASE + 8 */ + /* Set the buffer size and playout gain. */ + ulAddress += 4; + + /* Check if we are setting the duration modulo. This would be the last event and this */ + /* event is of a very specific size. */ + if ( ( fRepeatCountSet == TRUE ) + && ( ulEventIndex == ( ulEventsToCreate - 1 ) ) + && ( ulDurationModulo != 0x0 ) ) + { + /* The duration modulo variable contains all that is needed here. */ + ulBufferLength = ulDurationModulo; + } + ulTempData = ulBufferLength; + + /* Adjust playout gain. */ + if ( f_pBufferPlayoutAdd->lGainDb != 0 ) + { + /* Convert the dB value into OctFloat format. */ + usTempData = Oct6100ApiDbAmpHalfToOctFloat( f_pBufferPlayoutAdd->lGainDb ); + ulTempData |= ( usTempData & 0xFF00 ) << 16; + } + else + { + ulTempData |= cOCT6100_PLAYOUT_GAIN; + } + + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulAddress, ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* EVENT BASE + 0xC */ + ulAddress += 4; + ulTempData = ( ulBufferLength - 1 ) & 0xFFFFFFC0; /* Must be multiple of 64 bytes */ + + /* Adjust playout gain. */ + if ( f_pBufferPlayoutAdd->lGainDb != 0 ) + { + ulTempData |= ( usTempData & 0xFF ) << 24; + } + + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulAddress, ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Next event. */ + ulWritePtr++; + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Increment the write pointer to make it point to the next empty entry. */ + + if ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + pEchoChannel->ulRinBufWritePtr = ( pEchoChannel->ulRinBufWritePtr + ulEventsToCreate ) & ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - 1 ); + /* Remember that a buffer was added on the rin port. */ + pEchoChannel->fRinBufAdded = TRUE; + } + else /* f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + pEchoChannel->ulSoutBufWritePtr = ( pEchoChannel->ulSoutBufWritePtr + ulEventsToCreate ) & ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - 1 ); + /* Remember that a buffer was added on the sout port. */ + pEchoChannel->fSoutBufAdded = TRUE; + } + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutStartSer + +Description: Starts buffer playout on a channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutStart Pointer to buffer playout start structure. + +f_ulPlayoutStopEventType Playout stop event type to be generated if required. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutStartSer +UINT32 Oct6100BufferPlayoutStartSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart, + IN UINT32 f_ulPlayoutStopEventType ) +{ + UINT32 ulBufferIndex = 0; + UINT32 ulChannelIndex; + BOOL fNotifyOnPlayoutStop; + UINT32 ulUserEventId; + BOOL fAddToCurrentlyPlayingList; + UINT32 ulResult; + + /* Check the user's configuration of the buffer for errors. */ + ulResult = Oct6100ApiCheckPlayoutStartParams( f_pApiInstance, f_pBufferPlayoutStart, &ulChannelIndex, &ulBufferIndex, &fNotifyOnPlayoutStop, &ulUserEventId, &fAddToCurrentlyPlayingList ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write to all resources needed to activate buffer playout. */ + ulResult = Oct6100ApiWriteChanPlayoutStructs( f_pApiInstance, f_pBufferPlayoutStart, ulChannelIndex, ulBufferIndex, fNotifyOnPlayoutStop, ulUserEventId, fAddToCurrentlyPlayingList, f_ulPlayoutStopEventType ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckPlayoutStartParams + +Description: Check the validity of the channel and buffer requested. + Check the validity of the flags requested. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutStart Pointer to buffer playout start structure. +f_pulChannelIndex Pointer to the channel index of the selected channel. +f_pulBufferIndex Pointer to the buffer index within the API's buffer list. +f_pfNotifyOnPlayoutStop Pointer to the notify on playout stop flag. +f_pulUserEventId Pointer to the user event id specified. +f_pfAllowStartIfActive Pointer to the add to currently playing list flag. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckPlayoutStartParams +UINT32 Oct6100ApiCheckPlayoutStartParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart, + OUT PUINT32 f_pulChannelIndex, + OUT PUINT32 f_pulBufferIndex, + OUT PBOOL f_pfNotifyOnPlayoutStop, + OUT PUINT32 f_pulUserEventId, + OUT PBOOL f_pfAllowStartIfActive ) +{ + tPOCT6100_API_CHANNEL pEchoChannel; + UINT32 ulEntryOpenCnt; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxPlayoutBuffers == 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_DISABLED; + + if ( f_pBufferPlayoutStart->ulChannelHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + if ( f_pBufferPlayoutStart->ulPlayoutPort != cOCT6100_CHANNEL_PORT_ROUT && + f_pBufferPlayoutStart->ulPlayoutPort != cOCT6100_CHANNEL_PORT_SOUT ) + return cOCT6100_ERR_BUFFER_PLAYOUT_PLAYOUT_PORT; + + if ( f_pBufferPlayoutStart->fNotifyOnPlayoutStop != FALSE + && f_pBufferPlayoutStart->fNotifyOnPlayoutStop != TRUE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_NOTIFY_ON_STOP; + + if ( f_pBufferPlayoutStart->fAllowStartWhileActive != FALSE + && f_pBufferPlayoutStart->fAllowStartWhileActive != TRUE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_ALLOW_ACTIVE; + + /*=====================================================================*/ + /* Check the channel handle. */ + + if ( (f_pBufferPlayoutStart->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + *f_pulChannelIndex = f_pBufferPlayoutStart->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK; + if ( *f_pulChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChannel, *f_pulChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pBufferPlayoutStart->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChannel->fReserved != TRUE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChannel->byEntryOpenCnt ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + /* The channel cannot be in POWER_DOWN or HT_FREEZE to start the playout. */ + if ( ( pEchoChannel->byEchoOperationMode == cOCT6100_ECHO_OP_MODE_POWER_DOWN ) + || ( pEchoChannel->byEchoOperationMode == cOCT6100_ECHO_OP_MODE_HT_FREEZE ) ) + return cOCT6100_ERR_BUFFER_PLAYOUT_ECHO_OP_MODE; + + /* The channel's NLP must be enabled for playout to occur. */ + if ( pEchoChannel->VqeConfig.fEnableNlp == FALSE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_NLP_DISABLED; + + /*=====================================================================*/ + + /*=====================================================================*/ + /* Check if the user activated the buffer playout events. */ + + if ( f_pBufferPlayoutStart->fNotifyOnPlayoutStop == TRUE + && f_pApiInstance->pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize == 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_DISABLED; + + /*=====================================================================*/ + + /*=====================================================================*/ + /* Check if there is actually a buffer added in the list. */ + + if ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + if ( pEchoChannel->fRinBufAdded == FALSE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_LIST_EMPTY; + } + else /* if ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) */ + { + if ( pEchoChannel->fSoutBufAdded == FALSE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_LIST_EMPTY; + } + + /*=====================================================================*/ + + /* Return the requested information. */ + *f_pfNotifyOnPlayoutStop = f_pBufferPlayoutStart->fNotifyOnPlayoutStop; + *f_pulUserEventId = f_pBufferPlayoutStart->ulUserEventId; + *f_pfAllowStartIfActive = f_pBufferPlayoutStart->fAllowStartWhileActive; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteChanPlayoutStructs + +Description: Write the buffer playout event in the channel main structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutStart Pointer to buffer playout start structure. +f_ulChannelIndex Index of the channel within the API's channel list. +f_ulBufferIndex Index of the buffer within the API's buffer list. +f_fNotifyOnPlayoutStop Flag for the notify on playout stop. +f_ulUserEventId User event id passed to the user when a playout event is generated. +f_fAllowStartIfActive Add to currently playing list flag. +f_ulPlayoutStopEventType Playout stop event type to be generated if required. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteChanPlayoutStructs +UINT32 Oct6100ApiWriteChanPlayoutStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulBufferIndex, + IN BOOL f_fNotifyOnPlayoutStop, + IN UINT32 f_ulUserEventId, + IN BOOL f_fAllowStartIfActive, + IN UINT32 f_ulPlayoutStopEventType ) +{ + tPOCT6100_API_BUFFER pBufferEntry; + tPOCT6100_API_CHANNEL pEchoChannel; + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_READ_PARAMS ReadParams; + + UINT32 ulResult; + + UINT32 ulWritePtr; + UINT32 ulChipWritePtr; + PUINT32 pulSkipPtr; + UINT32 ulWritePtrBytesOfst; + UINT32 ulSkipPtrBytesOfst; + UINT32 ulWritePtrBitOfst; + UINT32 ulSkipPtrBitOfst; + UINT32 ulWritePtrFieldSize; + UINT32 ulSkipPtrFieldSize; + + UINT32 ulIgnoreBytesOfst; + UINT32 ulIgnoreBitOfst; + UINT32 ulIgnoreFieldSize; + + UINT32 ulHardSkipBytesOfst; + UINT32 ulHardSkipBitOfst; + UINT32 ulHardSkipFieldSize; + + UINT32 ulReadPtrBytesOfst; + UINT32 ulReadPtrBitOfst; + UINT32 ulReadPtrFieldSize; + + UINT32 ulPlayoutBaseAddress; + UINT32 ulAddress; + UINT32 ulTempData; + UINT32 ulMask; + UINT32 ulReadData; + UINT32 ulReadPtr; + UINT32 ulLoopCnt = 0; + + UINT16 usReadData; + + BOOL fBufferPlayoutStopDetected; + BOOL fWriteSkipPtr = FALSE; + BOOL fStillPlaying = TRUE; + + UINT32 aulWaitTime[ 2 ]; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChannel, f_ulChannelIndex ); + mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBufferEntry, f_ulBufferIndex ); + + /* First off, check for buffer playout events, if requested for this channel/port. */ + /* At the same time, if requested, check that the playout has stopped for this channel/port. */ + if ( ( ( pEchoChannel->fRinBufPlaying == TRUE ) + && ( ( pEchoChannel->fRinBufPlayoutNotifyOnStop == TRUE ) || ( f_fAllowStartIfActive == FALSE ) ) + && ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) ) + || ( ( ( pEchoChannel->fSoutBufPlaying == TRUE ) || ( f_fAllowStartIfActive == FALSE ) ) + && ( pEchoChannel->fSoutBufPlayoutNotifyOnStop == TRUE ) + && ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) ) ) + { + /* Buffer playout might still be going on for this channel/port. */ + ulResult = Oct6100BufferPlayoutCheckForSpecificEvent( f_pApiInstance, + f_ulChannelIndex, + f_pBufferPlayoutStart->ulPlayoutPort, + pEchoChannel->fRinBufPlayoutNotifyOnStop, + &fBufferPlayoutStopDetected ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the user requested to only start if playout is over. Return an error if */ + /* buffer playout is still going on on this channel/port. */ + if ( ( f_fAllowStartIfActive == FALSE ) && ( fBufferPlayoutStopDetected == FALSE ) ) + { + /* No go! User should wait for the current list to stop, or call the */ + /* Oct6100BufferPlayoutStop function. */ + return cOCT6100_ERR_BUFFER_PLAYOUT_STILL_ACTIVE; + } + } + + /* Select the buffer of interest. */ + if ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + ulWritePtr = pEchoChannel->ulRinBufWritePtr; + pulSkipPtr = &pEchoChannel->ulRinBufSkipPtr; + + ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.usDwordOffset * 4; + ulSkipPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinSkipPtrOfst.usDwordOffset * 4; + ulIgnoreBytesOfst = pSharedInfo->MemoryMap.PlayoutRinIgnoreSkipCleanOfst.usDwordOffset * 4; + ulHardSkipBytesOfst = pSharedInfo->MemoryMap.PlayoutRinHardSkipOfst.usDwordOffset * 4; + ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.usDwordOffset * 4; + + ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byBitOffset; + ulSkipPtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinSkipPtrOfst.byBitOffset; + ulIgnoreBitOfst = pSharedInfo->MemoryMap.PlayoutRinIgnoreSkipCleanOfst.byBitOffset; + ulHardSkipBitOfst = pSharedInfo->MemoryMap.PlayoutRinHardSkipOfst.byBitOffset; + ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byBitOffset; + + ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byFieldSize; + ulSkipPtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinSkipPtrOfst.byFieldSize; + ulIgnoreFieldSize = pSharedInfo->MemoryMap.PlayoutRinIgnoreSkipCleanOfst.byFieldSize; + ulHardSkipFieldSize = pSharedInfo->MemoryMap.PlayoutRinHardSkipOfst.byFieldSize; + ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byFieldSize; + } + else /* f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + ulWritePtr = pEchoChannel->ulSoutBufWritePtr; + pulSkipPtr = &pEchoChannel->ulSoutBufSkipPtr; + + ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.usDwordOffset * 4; + ulSkipPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutSkipPtrOfst.usDwordOffset * 4; + ulIgnoreBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutIgnoreSkipCleanOfst.usDwordOffset * 4; + ulHardSkipBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutHardSkipOfst.usDwordOffset * 4; + ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.usDwordOffset * 4; + + ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byBitOffset; + ulSkipPtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutSkipPtrOfst.byBitOffset; + ulIgnoreBitOfst = pSharedInfo->MemoryMap.PlayoutSoutIgnoreSkipCleanOfst.byBitOffset; + ulHardSkipBitOfst = pSharedInfo->MemoryMap.PlayoutSoutHardSkipOfst.byBitOffset; + ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byBitOffset; + + ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byFieldSize; + ulSkipPtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutSkipPtrOfst.byFieldSize; + ulIgnoreFieldSize = pSharedInfo->MemoryMap.PlayoutSoutIgnoreSkipCleanOfst.byFieldSize; + ulHardSkipFieldSize = pSharedInfo->MemoryMap.PlayoutSoutHardSkipOfst.byFieldSize; + ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byFieldSize; + } + + + + /* Set the playout feature base address. */ + ulPlayoutBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_ulChannelIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + + /* Check if we must wait for stop to complete before starting a new list. */ + if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == FALSE ) + { + if ( ( ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) && ( pEchoChannel->fRinHardStop == TRUE ) ) + || ( ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) && ( pEchoChannel->fSoutHardStop == TRUE ) ) ) + { + /* Read the read pointer. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + ReadParams.ulReadAddress = ulPlayoutBaseAddress + ulReadPtrBytesOfst; + + /* Get the write pointer in the chip. */ + ulAddress = ulPlayoutBaseAddress + ulWritePtrBytesOfst; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, pEchoChannel, ulAddress, &ulReadData, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulWritePtrFieldSize, ulWritePtrBitOfst, &ulMask ); + + /* Store the write pointer. */ + ulChipWritePtr = ( ulReadData & ulMask ) >> ulWritePtrBitOfst; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulReadPtrBitOfst < 16 ) + ReadParams.ulReadAddress += 2; + + while( fStillPlaying == TRUE ) + { + /* Read the read pointer until equals to the write pointer. */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulReadPtrBitOfst < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + mOCT6100_CREATE_FEATURE_MASK( ulReadPtrFieldSize, ulReadPtrBitOfst, &ulMask ); + + /* Store the read pointer. */ + ulReadPtr = ( ulTempData & ulMask ) >> ulReadPtrBitOfst; + + /* Playout has finished when the read pointer reaches the write pointer. */ + if ( ulReadPtr == ulChipWritePtr ) + break; + + ulLoopCnt++; + if( ulLoopCnt > cOCT6100_MAX_LOOP ) + { + return cOCT6100_ERR_FATAL_E6; + } + + aulWaitTime[ 0 ] = 100; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Check if must clear the skip bit. */ + if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == FALSE ) + { + if ( ( pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip == TRUE ) + && ( pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip == TRUE ) ) + { + /* Make sure the skip bit is cleared to start playout! */ + ulAddress = ulPlayoutBaseAddress + ulIgnoreBytesOfst; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, pEchoChannel, ulAddress, &ulTempData, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulIgnoreFieldSize, ulIgnoreBitOfst, &ulMask ); + + /* Cleared! */ + ulTempData &= ( ~ulMask ); + + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Make sure the hard skip bit is cleared to start playout! */ + ulAddress = ulPlayoutBaseAddress + ulHardSkipBytesOfst; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pEchoChannel, + ulAddress, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulIgnoreFieldSize, ulHardSkipBitOfst, &ulMask ); + + /* Cleared! */ + ulTempData &= ( ~ulMask ); + + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Write the skip and write pointer to activate buffer playout. */ + + /* Update the skip pointer. */ + if ( ( pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip == FALSE ) + || ( pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip == FALSE ) ) + { + /* Old 31 events image. */ + if ( ( ( ulWritePtr - *pulSkipPtr ) & 0x7F ) > 63 ) + { + *pulSkipPtr = ( ulWritePtr - 63 ) & 0x7F; + fWriteSkipPtr = TRUE; + } + } + else + { + /* No need to update the skip pointer, a bit needs to be set when skipping. */ + /* fWriteSkipPtr set to FALSE from variable declaration. */ + } + + if ( fWriteSkipPtr == TRUE ) + { + /*=======================================================================*/ + /* Fetch and modify the skip pointer. */ + + ulAddress = ulPlayoutBaseAddress + ulSkipPtrBytesOfst; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pEchoChannel, + ulAddress, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulSkipPtrFieldSize, ulSkipPtrBitOfst, &ulMask ); + + ulTempData &= ( ~ulMask ); + ulTempData |= *pulSkipPtr << ulSkipPtrBitOfst; + + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + } + + + /*=======================================================================*/ + /* Fetch and modify the write pointer. */ + + ulAddress = ulPlayoutBaseAddress + ulWritePtrBytesOfst; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pEchoChannel, + ulAddress, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulWritePtrFieldSize, ulWritePtrBitOfst, &ulMask ); + + ulTempData &= ( ~ulMask ); + ulTempData |= ulWritePtr << ulWritePtrBitOfst; + + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Now update the state of the channel stating that the buffer playout is activated. */ + + /* Select the buffer of interest.*/ + if ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + /* Check if the global ports active stat must be incremented. */ + if ( pEchoChannel->fRinBufPlaying == FALSE ) + { + /* Increment the number of active buffer playout ports. */ + pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts++; + } + + pEchoChannel->fRinBufPlaying = TRUE; + /* Keep the new notify on event flag. */ + pEchoChannel->fRinBufPlayoutNotifyOnStop = (UINT8)( f_fNotifyOnPlayoutStop & 0xFF ); + /* Keep the specified user event id. */ + pEchoChannel->ulRinUserBufPlayoutEventId = f_ulUserEventId; + /* Keep type of event to be generated. */ + pEchoChannel->byRinPlayoutStopEventType = (UINT8)( f_ulPlayoutStopEventType & 0xFF ); + /* No hard stop for now. */ + pEchoChannel->fRinHardStop = FALSE; + /* No buffer added in the rin list for now. */ + pEchoChannel->fRinBufAdded = FALSE; + /* Buffer playout is active on this channel. */ + pEchoChannel->fBufPlayoutActive = TRUE; + } + else /* f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + /* Check if the global ports active stat must be incremented. */ + if ( pEchoChannel->fSoutBufPlaying == FALSE ) + { + /* Increment the number of active buffer playout ports. */ + pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts++; + } + + pEchoChannel->fSoutBufPlaying = TRUE; + /* Keep the new notify on event flag. */ + pEchoChannel->fSoutBufPlayoutNotifyOnStop = (UINT8)( f_fNotifyOnPlayoutStop & 0xFF ); + /* Keep the specified user event id. */ + pEchoChannel->ulSoutUserBufPlayoutEventId = f_ulUserEventId; + /* Keep type of event to be generated. */ + pEchoChannel->bySoutPlayoutStopEventType = (UINT8)( f_ulPlayoutStopEventType & 0xFF ); + /* No hard stop for now. */ + pEchoChannel->fSoutHardStop = FALSE; + /* No buffer added in the sout list for now. */ + pEchoChannel->fSoutBufAdded = FALSE; + /* Buffer playout is active on this channel. */ + pEchoChannel->fBufPlayoutActive = TRUE; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutStopSer + +Description: Stops buffer playout on a channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutStop Pointer to buffer playout stop structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutStopSer +UINT32 Oct6100BufferPlayoutStopSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop ) +{ + UINT32 ulChannelIndex; + UINT16 usEchoMemIndex; + UINT32 ulResult; + + /* Check the user's configuration of the buffer for errors. */ + ulResult = Oct6100ApiAssertPlayoutStopParams( + f_pApiInstance, + f_pBufferPlayoutStop, + &ulChannelIndex, + &usEchoMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write to all resources needed to deactivate buffer playout. */ + ulResult = Oct6100ApiInvalidateChanPlayoutStructs( + f_pApiInstance, + f_pBufferPlayoutStop, + ulChannelIndex, + usEchoMemIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertPlayoutStopParams + +Description: Check the validity of the channel and buffer requested. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutStop Pointer to buffer playout stop structure. +f_pulChannelIndex Pointer to the channel index on which playout is to be stopped. +f_pusEchoMemIndex Pointer to the echo mem index on which playout is to be stopped. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertPlayoutStopParams +UINT32 Oct6100ApiAssertPlayoutStopParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop, + OUT PUINT32 f_pulChannelIndex, + OUT PUINT16 f_pusEchoMemIndex ) +{ + tPOCT6100_API_CHANNEL pEchoChannel; + UINT32 ulEntryOpenCnt; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxPlayoutBuffers == 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_DISABLED; + + if ( f_pBufferPlayoutStop->ulChannelHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + if ( f_pBufferPlayoutStop->ulPlayoutPort != cOCT6100_CHANNEL_PORT_ROUT && + f_pBufferPlayoutStop->ulPlayoutPort != cOCT6100_CHANNEL_PORT_SOUT ) + return cOCT6100_ERR_BUFFER_PLAYOUT_PLAYOUT_PORT; + + if ( f_pBufferPlayoutStop->fStopCleanly != TRUE && f_pBufferPlayoutStop->fStopCleanly != FALSE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_STOP_CLEANLY; + + /*=====================================================================*/ + /* Check the channel handle. */ + + if ( (f_pBufferPlayoutStop->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + *f_pulChannelIndex = f_pBufferPlayoutStop->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK; + if ( *f_pulChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChannel, *f_pulChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pBufferPlayoutStop->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChannel->fReserved != TRUE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChannel->byEntryOpenCnt ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + /* Return echo memory index. */ + *f_pusEchoMemIndex = pEchoChannel->usEchoMemIndex; + + /* Check if buffer playout is active for the selected port. */ + if ( ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + && ( pEchoChannel->fRinBufPlaying == FALSE ) + && ( pEchoChannel->fRinBufAdded == FALSE ) ) + return cOCT6100_ERR_BUFFER_PLAYOUT_NOT_STARTED; + + if ( ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) + && ( pEchoChannel->fSoutBufPlaying == FALSE ) + && ( pEchoChannel->fSoutBufAdded == FALSE ) ) + return cOCT6100_ERR_BUFFER_PLAYOUT_NOT_STARTED; + + /*=====================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInvalidateChanPlayoutStructs + +Description: Write the buffer playout event in the channel main structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutStop Pointer to buffer playout stop structure. +f_ulChannelIndex Index of the channel within the API's channel list. +f_usEchoMemIndex Index of the echo channel in hardware memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInvalidateChanPlayoutStructs +UINT32 Oct6100ApiInvalidateChanPlayoutStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop, + IN UINT32 f_ulChannelIndex, + IN UINT16 f_usEchoMemIndex + + ) +{ + tPOCT6100_API_CHANNEL pEchoChannel; + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_WRITE_PARAMS WriteParams; + + UINT32 ulResult; + + UINT32 ulWritePtrBytesOfst; + UINT32 ulWritePtrBitOfst; + UINT32 ulWritePtrFieldSize; + UINT32 ulSkipPtrBytesOfst; + UINT32 ulSkipPtrBitOfst; + UINT32 ulSkipPtrFieldSize; + UINT32 ulIgnoreBytesOfst; + UINT32 ulIgnoreBitOfst; + UINT32 ulIgnoreFieldSize; + UINT32 ulHardSkipBytesOfst; + UINT32 ulHardSkipBitOfst; + UINT32 ulHardSkipFieldSize; + UINT32 ulReadPtrBytesOfst; + UINT32 ulReadPtrBitOfst; + UINT32 ulReadPtrFieldSize; + + UINT32 ulSkipPtr; + UINT32 ulWritePtr; + UINT32 ulReadPtr = 0; + UINT32 ulCurrentPtr; + + UINT32 ulPlayoutBaseAddress; + UINT32 ulAddress; + UINT32 ulTempData; + UINT32 ulMask; + UINT32 ulReadData; + + UINT16 usReadData; + BOOL fCheckStop = FALSE; + + UINT32 ulEventBuffer; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChannel, f_ulChannelIndex ); + + /* Select the port of interest. */ + if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + ulWritePtr = pEchoChannel->ulRinBufWritePtr; + ulSkipPtr = ulWritePtr; + + ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.usDwordOffset * 4; + ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byBitOffset; + ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byFieldSize; + + ulSkipPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinSkipPtrOfst.usDwordOffset * 4; + ulSkipPtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinSkipPtrOfst.byBitOffset; + ulSkipPtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinSkipPtrOfst.byFieldSize; + + ulIgnoreBytesOfst = pSharedInfo->MemoryMap.PlayoutRinIgnoreSkipCleanOfst.usDwordOffset * 4; + ulIgnoreBitOfst = pSharedInfo->MemoryMap.PlayoutRinIgnoreSkipCleanOfst.byBitOffset; + ulIgnoreFieldSize = pSharedInfo->MemoryMap.PlayoutRinIgnoreSkipCleanOfst.byFieldSize; + + ulHardSkipBytesOfst = pSharedInfo->MemoryMap.PlayoutRinHardSkipOfst.usDwordOffset * 4; + ulHardSkipBitOfst = pSharedInfo->MemoryMap.PlayoutRinHardSkipOfst.byBitOffset; + ulHardSkipFieldSize = pSharedInfo->MemoryMap.PlayoutRinHardSkipOfst.byFieldSize; + + ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.usDwordOffset * 4; + ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byBitOffset; + ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byFieldSize; + } + else /* f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + ulWritePtr = pEchoChannel->ulSoutBufWritePtr; + ulSkipPtr = ulWritePtr; + + ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.usDwordOffset * 4; + ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byBitOffset; + ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byFieldSize; + + ulSkipPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutSkipPtrOfst.usDwordOffset * 4; + ulSkipPtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutSkipPtrOfst.byBitOffset; + ulSkipPtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutSkipPtrOfst.byFieldSize; + + ulIgnoreBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutIgnoreSkipCleanOfst.usDwordOffset * 4; + ulIgnoreBitOfst = pSharedInfo->MemoryMap.PlayoutSoutIgnoreSkipCleanOfst.byBitOffset; + ulIgnoreFieldSize = pSharedInfo->MemoryMap.PlayoutSoutIgnoreSkipCleanOfst.byFieldSize; + + ulHardSkipBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutHardSkipOfst.usDwordOffset * 4; + ulHardSkipBitOfst = pSharedInfo->MemoryMap.PlayoutSoutHardSkipOfst.byBitOffset; + ulHardSkipFieldSize = pSharedInfo->MemoryMap.PlayoutSoutHardSkipOfst.byFieldSize; + + ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.usDwordOffset * 4; + ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byBitOffset; + ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byFieldSize; + } + + /* Set the playout feature base address. */ + ulPlayoutBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + + /* Check if something is currently playing. */ + if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + if ( pEchoChannel->fRinBufPlaying == TRUE ) + { + /* Check if we are stopping it or if it stopped by itself. */ + fCheckStop = TRUE; + } + else + { + /* Not playing! */ + if ( f_pBufferPlayoutStop->pfAlreadyStopped != NULL ) + *f_pBufferPlayoutStop->pfAlreadyStopped = TRUE; + } + } + else /* if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) */ + { + if ( pEchoChannel->fSoutBufPlaying == TRUE ) + { + /* Check if we are stopping it or if it stopped by itself. */ + fCheckStop = TRUE; + } + else + { + /* Not playing! */ + if ( f_pBufferPlayoutStop->pfAlreadyStopped != NULL ) + *f_pBufferPlayoutStop->pfAlreadyStopped = TRUE; + } + } + + if ( ( fCheckStop == TRUE ) || ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == TRUE ) ) + { + /* Read the read pointer. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + ReadParams.ulReadAddress = ulPlayoutBaseAddress + ulReadPtrBytesOfst; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulReadPtrBitOfst < 16 ) + ReadParams.ulReadAddress += 2; + + /* Must read in memory directly since this value is changed by hardware */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulReadPtrBitOfst < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + mOCT6100_CREATE_FEATURE_MASK( ulReadPtrFieldSize, ulReadPtrBitOfst, &ulMask ); + + /* Store the read pointer. */ + ulReadPtr = ( ulTempData & ulMask ) >> ulReadPtrBitOfst; + + /* Playout has finished when the read pointer reaches the write pointer. */ + if ( f_pBufferPlayoutStop->pfAlreadyStopped != NULL ) + { + if ( ulReadPtr != ulWritePtr ) + *f_pBufferPlayoutStop->pfAlreadyStopped = FALSE; + else /* if ( ulReadPtr == ulWritePtr ) */ + *f_pBufferPlayoutStop->pfAlreadyStopped = TRUE; + } + } + + /* If the skip bits are located in the event itself, the playout is stopped by setting the */ + /* skip pointer to the hardware chip write pointer. Read it directly from the NLP configuration. */ + if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == TRUE ) + { + if ( ulReadPtr != ulWritePtr ) + { + /* Get the write pointer in the chip. */ + ulAddress = ulPlayoutBaseAddress + ulWritePtrBytesOfst; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, pEchoChannel, ulAddress, &ulReadData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulWritePtrFieldSize, ulWritePtrBitOfst, &ulMask ); + + /* Store the write pointer. */ + ulWritePtr = ( ulReadData & ulMask ) >> ulWritePtrBitOfst; + ulSkipPtr = ulWritePtr; + } + } + + /* Check if must clear repeat bit. */ + if ( ( ( pEchoChannel->fRinBufPlayoutRepeatUsed == TRUE ) && ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) ) + || ( ( pEchoChannel->fSoutBufPlayoutRepeatUsed == TRUE ) && ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) ) ) + { + if ( ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == FALSE ) + || ( ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == TRUE ) + && ( ulWritePtr != ulReadPtr ) ) ) + { + if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + ulEventBuffer = pSharedInfo->MemoryMap.ulChanMainRinPlayoutMemOfst; + } + else /* f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + ulEventBuffer = pSharedInfo->MemoryMap.ulChanMainSoutPlayoutMemOfst; + } + + /* Set the playout event base address. */ + if ( ( pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip == TRUE ) + && ( pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip == TRUE ) ) + { + /* 127 or 31 events image. */ + ulAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoMemIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + ulEventBuffer + (cOCT6100_PLAYOUT_EVENT_MEM_SIZE * ( ( ulWritePtr - 1 ) & ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - 1 ))); + } + else + { + /* Old 31 events image. */ + ulAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoMemIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + ulEventBuffer + (cOCT6100_PLAYOUT_EVENT_MEM_SIZE * ( ( ulWritePtr - 1 ) & 0x1F)); + } + + /* EVENT BASE + 4 */ + /* Playout configuration. */ + ulAddress += 4; + + ReadParams.ulReadAddress = ulAddress; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Read-clear-write the new repeat bit. */ + usReadData &= 0x7FFF; + + WriteParams.ulWriteAddress = ulAddress; + WriteParams.usWriteData = usReadData; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Write the skip to the value of the write pointer to stop buffer playout. */ + + /*=======================================================================*/ + /* First set the ignore skip clean bit if required. */ + + if ( ( pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip == FALSE ) + || ( pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip == FALSE ) ) + { + ulAddress = ulPlayoutBaseAddress + ulIgnoreBytesOfst; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulIgnoreFieldSize, ulIgnoreBitOfst, &ulMask ); + + ulTempData &= ( ~ulMask ); + + /* Check if the skip need to be clean or not. */ + if ( f_pBufferPlayoutStop->fStopCleanly == FALSE ) + ulTempData |= 0x1 << ulIgnoreBitOfst; + + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Fetch and modify the write pointer. */ + + ulAddress = ulPlayoutBaseAddress + ulWritePtrBytesOfst; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, pEchoChannel, ulAddress, &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulWritePtrFieldSize, ulWritePtrBitOfst, &ulMask ); + + ulTempData &= ( ~ulMask ); + ulTempData |= ulWritePtr << ulWritePtrBitOfst; + + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Fetch and modify the skip pointer. */ + + ulAddress = ulPlayoutBaseAddress + ulSkipPtrBytesOfst; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulSkipPtrFieldSize, ulSkipPtrBitOfst, &ulMask ); + + ulTempData &= ( ~ulMask ); + ulTempData |= ulSkipPtr << ulSkipPtrBitOfst; + + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* If in the new buffer playout case, things are in a different order. */ + + if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == FALSE ) + { + if ( ( pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip == TRUE ) + && ( pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip == TRUE ) ) + { + ulAddress = ulPlayoutBaseAddress + ulHardSkipBytesOfst; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulHardSkipFieldSize, ulHardSkipBitOfst, &ulMask ); + + ulTempData &= ( ~ulMask ); + + /* Check if the skip need to be clean or not. */ + if ( f_pBufferPlayoutStop->fStopCleanly == FALSE ) + ulTempData |= 0x1 << ulHardSkipBitOfst; + + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now is the appropriate time to skip! */ + ulAddress = ulPlayoutBaseAddress + ulIgnoreBytesOfst; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulIgnoreFieldSize, ulIgnoreBitOfst, &ulMask ); + + ulTempData &= ( ~ulMask ); + + /* Set the skip bit. */ + ulTempData |= 0x1 << ulIgnoreBitOfst; + + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* The API must set the skip bit in all the events that are queued. */ + + if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == TRUE ) + { + if ( fCheckStop == TRUE ) + { + if ( ulReadPtr != ulWritePtr ) + { + if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + ulEventBuffer = pSharedInfo->MemoryMap.ulChanMainRinPlayoutMemOfst; + } + else /* f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + ulEventBuffer = pSharedInfo->MemoryMap.ulChanMainSoutPlayoutMemOfst; + } + + for ( ulCurrentPtr = ulReadPtr; ulCurrentPtr != ulWritePtr; ) + { + /* Set the playout event base address. */ + + /* 127 or 31 events image. */ + ulAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoMemIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + ulEventBuffer + ( cOCT6100_PLAYOUT_EVENT_MEM_SIZE * ulCurrentPtr ); + ulCurrentPtr++; + ulCurrentPtr &= ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - 1 ); + + /* EVENT BASE + 0 playout configuration. */ + WriteParams.ulWriteAddress = ulAddress; + + /* Set skip bit + hard-skip bit. */ + WriteParams.usWriteData = 0x8000; + if ( f_pBufferPlayoutStop->fStopCleanly == FALSE ) + WriteParams.usWriteData |= 0x4000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + } + + /*=======================================================================*/ + /* If stop immediatly, wait the stop before leaving the function. */ + + if ( f_pBufferPlayoutStop->fStopCleanly == FALSE ) + { + /* Remember that an "hard stop" was used for the next start. */ + if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + pEchoChannel->fRinHardStop = TRUE; + else /* if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) */ + pEchoChannel->fSoutHardStop = TRUE; + } + + /*=======================================================================*/ + /* Update the channel entry to set the playing flag to FALSE. */ + + /* Select the port of interest. */ + if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + /* Check if the global ports active stat must be decremented. */ + if ( pEchoChannel->fRinBufPlaying == TRUE ) + { + /* Decrement the number of active buffer playout ports. */ + pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts--; + } + + pEchoChannel->fRinBufPlaying = FALSE; + + /* Return user information. */ + if ( f_pBufferPlayoutStop->pfNotifyOnPlayoutStop != NULL ) + *f_pBufferPlayoutStop->pfNotifyOnPlayoutStop = pEchoChannel->fRinBufPlayoutNotifyOnStop; + + /* Make sure no new event is recorded for this channel/port. */ + pEchoChannel->fRinBufPlayoutNotifyOnStop = FALSE; + if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == TRUE ) + { + pEchoChannel->ulRinBufSkipPtr = ulSkipPtr; + pEchoChannel->ulRinBufWritePtr = ulWritePtr; + } + else /* if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == FALSE ) */ + pEchoChannel->ulRinBufSkipPtr = pEchoChannel->ulRinBufWritePtr; + + /* The repeat flag can now be used. */ + pEchoChannel->fRinBufPlayoutRepeatUsed = FALSE; + + /* For sure, all buffers have now been cleared on the Rin port. */ + pEchoChannel->fRinBufAdded = FALSE; + + /* Clear optimization flag if possible. */ + if ( ( pEchoChannel->fSoutBufPlaying == FALSE ) + && ( pEchoChannel->fSoutBufPlayoutNotifyOnStop == FALSE ) ) + { + /* Buffer playout is no more active on this channel. */ + pEchoChannel->fBufPlayoutActive = FALSE; + } + } + else /* f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + /* Check if the global ports active stat must be decremented. */ + if ( pEchoChannel->fSoutBufPlaying == TRUE ) + { + /* Decrement the number of active buffer playout ports. */ + pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts--; + } + + pEchoChannel->fSoutBufPlaying = FALSE; + + /* Return user information. */ + if ( f_pBufferPlayoutStop->pfNotifyOnPlayoutStop != NULL ) + *f_pBufferPlayoutStop->pfNotifyOnPlayoutStop = pEchoChannel->fSoutBufPlayoutNotifyOnStop; + + /* Make sure no new event is recorded for this channel/port. */ + pEchoChannel->fSoutBufPlayoutNotifyOnStop = FALSE; + if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == TRUE ) + { + pEchoChannel->ulSoutBufSkipPtr = ulSkipPtr; + pEchoChannel->ulSoutBufWritePtr = ulWritePtr; + } + else /* if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == FALSE ) */ + pEchoChannel->ulSoutBufSkipPtr = pEchoChannel->ulSoutBufWritePtr; + + /* The repeat flag can now be used. */ + pEchoChannel->fSoutBufPlayoutRepeatUsed = FALSE; + + /* For sure, all buffers have now been cleared on the Sout port. */ + pEchoChannel->fSoutBufAdded = FALSE; + + /* Clear optimization flag if possible. */ + if ( ( pEchoChannel->fRinBufPlaying == FALSE ) + && ( pEchoChannel->fRinBufPlayoutNotifyOnStop == FALSE ) ) + { + /* Buffer playout is no more active on this channel. */ + pEchoChannel->fBufPlayoutActive = FALSE; + } + } + + /*=======================================================================*/ + + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveBufPlayoutListEntry + +Description: Reserves a free entry in the Buffer playout list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pulBufferIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveBufPlayoutListEntry +UINT32 Oct6100ApiReserveBufPlayoutListEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT32 f_pulBufferIndex ) +{ + PVOID pBufPlayoutAlloc; + UINT32 ulResult; + + mOCT6100_GET_BUFFER_ALLOC_PNT( f_pApiInstance->pSharedInfo, pBufPlayoutAlloc ) + + ulResult = OctapiLlmAllocAlloc( pBufPlayoutAlloc, f_pulBufferIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_BUFFER_PLAYOUT_ALL_BUFFERS_OPEN; + else + return cOCT6100_ERR_FATAL_40; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseBufPlayoutListEntry + +Description: Release an entry from the Buffer playout list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulBufferIndex List entry to be freed. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseBufPlayoutListEntry +UINT32 Oct6100ApiReleaseBufPlayoutListEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulBufferIndex ) +{ + PVOID pBufPlayoutAlloc; + UINT32 ulResult; + + mOCT6100_GET_BUFFER_ALLOC_PNT( f_pApiInstance->pSharedInfo, pBufPlayoutAlloc ) + + ulResult = OctapiLlmAllocDealloc( pBufPlayoutAlloc, f_ulBufferIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_41; + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_remote_debug.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_remote_debug.c new file mode 100644 index 0000000..8afb2f9 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_remote_debug.c @@ -0,0 +1,1598 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_remote_debug.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the routines used for remote debugging. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 35 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" + +#include "apilib/octapi_bt0.h" +#include "apilib/octapi_largmath.h" + +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_debug_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_remote_debug_pub.h" + +#include "octrpc/rpc_protocol.h" +#include "octrpc/oct6100_rpc_protocol.h" + +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_chip_open_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_debug_priv.h" +#include "oct6100_remote_debug_priv.h" + +/**************************** PUBLIC FUNCTIONS *****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100RemoteDebug + +Description: This function interprets the remote debugging packets received + by the user’s software. Commands contained in the packet are + executed by the API. In addition, a response packet is + constructed and returned by the function. It is the responsibility + of the user’s software to transmit the response packet back to + the source of the debugging packet. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pRemoteDebug Pointer to a remote debug structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100RemoteDebugDef +UINT32 Oct6100RemoteDebugDef( + tPOCT6100_REMOTE_DEBUG f_pRemoteDebug ) +{ + f_pRemoteDebug->pulReceivedPktPayload = NULL; + f_pRemoteDebug->ulReceivedPktLength = 0; + f_pRemoteDebug->pulResponsePktPayload = NULL; + f_pRemoteDebug->ulMaxResponsePktLength = 0; + f_pRemoteDebug->ulResponsePktLength = 0; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100RemoteDebug +UINT32 Oct6100RemoteDebug( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_REMOTE_DEBUG f_pRemoteDebug ) +{ + tPOCTRPC_OGRDTP_HEADER pOgrdtpHeader; + tPOCTRPC_INTERFACE_HEADER pInterfaceHeader; + tPOCTRPC_COMMAND_HEADER pRspCmndHeader; + PUINT32 pulRcvPktPayload; + PUINT32 pulRspPktPayload; + UINT32 ulPktLengthDword; + UINT32 ulSessionIndex; + UINT32 ulChecksum; + UINT32 ulResult; + + /* Check for errors. */ + if ( f_pRemoteDebug->pulReceivedPktPayload == NULL ) + return cOCT6100_ERR_REMOTEDEBUG_RECEIVED_PKT_PAYLOAD; + if ( f_pRemoteDebug->pulResponsePktPayload == NULL ) + return cOCT6100_ERR_REMOTEDEBUG_RESPONSE_PKT_PAYLOAD; + if ( f_pRemoteDebug->ulReceivedPktLength < cOCTRPC_MIN_PACKET_BYTE_LENGTH ) + return cOCT6100_ERR_REMOTEDEBUG_RECEIVED_PKT_LENGTH; + if ( f_pRemoteDebug->ulReceivedPktLength > cOCTRPC_MAX_PACKET_BYTE_LENGTH ) + return cOCT6100_ERR_REMOTEDEBUG_RECEIVED_PKT_LENGTH; + if ( f_pRemoteDebug->ulMaxResponsePktLength < f_pRemoteDebug->ulReceivedPktLength ) + return cOCT6100_ERR_REMOTEDEBUG_RESPONSE_PKT_LENGTH; + if ( (f_pRemoteDebug->ulReceivedPktLength % 4) != 0 ) + return cOCT6100_ERR_REMOTEDEBUG_RECEIVED_PKT_LENGTH; + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxRemoteDebugSessions == 0 ) + return cOCT6100_ERR_REMOTEDEBUG_DISABLED; + + /* Set response length as received length. */ + f_pRemoteDebug->ulResponsePktLength = f_pRemoteDebug->ulReceivedPktLength; + + /* Typecast the packet payload to local pointers. */ + pOgrdtpHeader = ( tPOCTRPC_OGRDTP_HEADER )f_pRemoteDebug->pulReceivedPktPayload; + pInterfaceHeader = ( tPOCTRPC_INTERFACE_HEADER )(f_pRemoteDebug->pulReceivedPktPayload + (sizeof( tOCTRPC_OGRDTP_HEADER ) / 4)); + + /* Get local pointer to received and response packet payloads. */ + pulRcvPktPayload = f_pRemoteDebug->pulReceivedPktPayload; + pulRspPktPayload = f_pRemoteDebug->pulResponsePktPayload; + + /* Get the length of the packet in UINT32s. */ + ulPktLengthDword = f_pRemoteDebug->ulReceivedPktLength / 4; + + /* Check the endian detection field to determine if the payload must be */ + /* swapped to account for different endian formats. */ + ulResult = Oct6100ApiCheckEndianDetectField( pOgrdtpHeader, ulPktLengthDword ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check the packet's length. */ + if ( pOgrdtpHeader->ulPktByteSize != f_pRemoteDebug->ulReceivedPktLength ) + return cOCT6100_ERR_REMOTEDEBUG_RECEIVED_PKT_LENGTH; + + /* Perform the sum of each word in the packet and compare to checksum. */ + Oct6100ApiCalculateChecksum( pulRcvPktPayload, ulPktLengthDword, &ulChecksum ); + if ( ulChecksum != pOgrdtpHeader->ulChecksum ) + return cOCT6100_ERR_REMOTEDEBUG_CHECKSUM; + + /* Check if the packet's session number has a corresponding entry in the API table. + If not then close an entry which has timed out, and allocate the entry to the + new session number. */ + ulResult = Oct6100ApiCheckSessionNum( f_pApiInstance, pOgrdtpHeader, &ulSessionIndex ); + if ( ulResult == cOCT6100_ERR_REMOTEDEBUG_ALL_SESSIONS_OPEN ) + { + Oct6100ApiFormResponsePkt( f_pApiInstance, pulRcvPktPayload, pulRspPktPayload, ulPktLengthDword, FALSE, FALSE, FALSE, FALSE, cOCT6100_INVALID_VALUE, cOCTRPC_RDBGERR_ALL_SESSIONS_OPEN, cOCT6100_INVALID_VALUE, ulChecksum ); + return cOCT6100_ERR_OK; + } + else if ( ulResult == cOCT6100_ERR_REMOTEDEBUG_TRANSACTION_ANSWERED ) + { + Oct6100ApiFormResponsePkt( f_pApiInstance, pulRcvPktPayload, pulRspPktPayload, ulPktLengthDword, TRUE, FALSE, FALSE, FALSE, ulSessionIndex, cOCT6100_INVALID_VALUE, cOCT6100_INVALID_VALUE, ulChecksum ); + return cOCT6100_ERR_OK; + } + else if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + /* Check if an echo packet. If so then there's no need to check the rest of + the packet. Simply copy the packet back to the output buffer, enter the + protocol number supported by this API compilation, and recalculate the + checksum. If the packet is not an echo packet and the protocol version + does not correspond to this compiled version then return the supported + protocol version. */ + if ( pOgrdtpHeader->ulRpcProtocolNum == cOCTRPC_ECHO_PROTOCOL ) + { + Oct6100ApiFormResponsePkt( f_pApiInstance, pulRcvPktPayload, pulRspPktPayload, ulPktLengthDword, FALSE, TRUE, FALSE, FALSE, ulSessionIndex, cOCT6100_INVALID_VALUE, cOCT6100_INVALID_VALUE, ulChecksum ); + return cOCT6100_ERR_OK; + } + else if ( pOgrdtpHeader->ulRpcProtocolNum != cOCTRPC_PROTOCOL_V1_1 ) + { + Oct6100ApiFormResponsePkt( f_pApiInstance, pulRcvPktPayload, pulRspPktPayload, ulPktLengthDword, FALSE, TRUE, FALSE, FALSE, ulSessionIndex, cOCTRPC_RDBGERR_PROTOCOL_NUMBER, cOCT6100_INVALID_VALUE, ulChecksum ); + return cOCT6100_ERR_OK; + } + else if ( f_pRemoteDebug->ulReceivedPktLength <= cOCTRPC_FIRST_COMMAND_BYTE_OFFSET ) + { + Oct6100ApiFormResponsePkt( f_pApiInstance, pulRcvPktPayload, pulRspPktPayload, ulPktLengthDword, FALSE, FALSE, FALSE, FALSE, ulSessionIndex, cOCTRPC_RDBGERR_NO_COMMAND_HEADER, cOCT6100_INVALID_VALUE, ulChecksum ); + return cOCT6100_ERR_OK; + } + + + /* Check the packet's RPC interface type and version. If either does not match then + return the packet with the supported interface type and version of this compilation. */ + if ( pInterfaceHeader->ulInterfaceVersion != cOCTRPC_INTERFACE_VERSION ) + { + Oct6100ApiFormResponsePkt( f_pApiInstance, pulRcvPktPayload, pulRspPktPayload, ulPktLengthDword, FALSE, FALSE, TRUE, TRUE, ulSessionIndex, cOCTRPC_RDBGERR_INTERFACE_VERSION, cOCT6100_INVALID_VALUE, ulChecksum ); + return cOCT6100_ERR_OK; + } + if ( pInterfaceHeader->ulInterfaceType != cOCTRPC_OCT6100_INTERFACE ) + { + Oct6100ApiFormResponsePkt( f_pApiInstance, pulRcvPktPayload, pulRspPktPayload, ulPktLengthDword, FALSE, FALSE, TRUE, TRUE, ulSessionIndex, cOCTRPC_RDBGERR_INTERFACE_TYPE, cOCT6100_INVALID_VALUE, ulChecksum ); + return cOCT6100_ERR_OK; + } + + /* Check each command header to make sure the indicated command and length agree. If + there is an error in the packet's commands then the response packet will be + constructed by the function. */ + ulResult = Oct6100ApiCheckPktCommands( f_pApiInstance, pulRcvPktPayload, pulRspPktPayload, ulSessionIndex, ulPktLengthDword, ulChecksum ); + if ( ulResult == cOCT6100_ERR_REMOTE_DEBUG_PARSING_ERROR ) + return cOCT6100_ERR_OK; + + /* The packet's fields are valid. Each command must now be extracted and executed. */ + Oct6100ApiExecutePktCommands( f_pApiInstance, pulRcvPktPayload, ulPktLengthDword ); + + pRspCmndHeader = ( tPOCTRPC_COMMAND_HEADER )(( PUINT32 )pulRspPktPayload + ((sizeof( tOCTRPC_OGRDTP_HEADER ) + sizeof( tOCTRPC_INTERFACE_HEADER )) / 4)); + + /* Verify if the new method of using the protocol is the selected case. */ + /* All commands have been executed. Calculate the packet's new checksum + and copy the packet to user provided buffer for response packet. */ + Oct6100ApiCalculateChecksum( pulRcvPktPayload, ulPktLengthDword, &ulChecksum ); + + /* Send response packet. */ + Oct6100ApiFormResponsePkt( f_pApiInstance, pulRcvPktPayload, pulRspPktPayload, ulPktLengthDword, FALSE, FALSE, FALSE, FALSE, ulSessionIndex, cOCTRPC_RDBGERR_OK, cOCT6100_INVALID_VALUE, ulChecksum ); + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetRemoteDebugSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of remote debugging. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pChipOpen Pointer to chip configuration struct. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetRemoteDebugSwSizes +UINT32 Oct6100ApiGetRemoteDebugSwSizes( + IN tPOCT6100_CHIP_OPEN f_pChipOpen, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + + /* Memory needed for remote debugging sessions. */ + if ( f_pChipOpen->ulMaxRemoteDebugSessions > 0 ) + { + f_pInstSizes->ulRemoteDebugList = f_pChipOpen->ulMaxRemoteDebugSessions * sizeof( tOCT6100_API_REMOTE_DEBUG_SESSION ); + + ulResult = octapi_bt0_get_size( f_pChipOpen->ulMaxRemoteDebugSessions, 4, 4, &f_pInstSizes->ulRemoteDebugTree ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_41; + + f_pInstSizes->ulRemoteDebugPktCache = cOCTRPC_MAX_PACKET_BYTE_LENGTH * f_pChipOpen->ulMaxRemoteDebugSessions; + f_pInstSizes->ulRemoteDebugDataBuf = cOCTRPC_MAX_PACKET_BYTE_LENGTH * 4; + } + else + { + f_pInstSizes->ulRemoteDebugList = 0; + f_pInstSizes->ulRemoteDebugTree = 0; + f_pInstSizes->ulRemoteDebugPktCache = 0; + f_pInstSizes->ulRemoteDebugDataBuf = 0; + } + + /* Round off the size. */ + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulRemoteDebugList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulRemoteDebugTree, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulRemoteDebugPktCache, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulRemoteDebugDataBuf, ulTempVar ) + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRemoteDebuggingSwInit + +Description: Initializes all portions of the API instance associated to + remote debugging. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRemoteDebuggingSwInit +UINT32 Oct6100ApiRemoteDebuggingSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pSessionTree; + UINT32 ulResult; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + pSharedInfo->RemoteDebugInfo.ulNumSessionsOpen = 0; + pSharedInfo->RemoteDebugInfo.ulMaxSessionsOpen = pSharedInfo->ChipConfig.usMaxRemoteDebugSessions; + pSharedInfo->RemoteDebugInfo.ulSessionListHead = cOCT6100_INVALID_VALUE; + pSharedInfo->RemoteDebugInfo.ulSessionListTail = cOCT6100_INVALID_VALUE; + + if ( pSharedInfo->ChipConfig.usMaxRemoteDebugSessions > 0 ) + { + mOCT6100_GET_REMOTE_DEBUG_TREE_PNT( pSharedInfo, pSessionTree ) + + ulResult = octapi_bt0_init( ( ( PVOID* )&pSessionTree ), pSharedInfo->ChipConfig.usMaxRemoteDebugSessions, 4, 4 ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_42; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckEndianDetectField + +Description: Checks the endian field of a packet and performs a swap of + the packet data if deemed necessary. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulPktLengthDword Length of the packet in dwords. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckEndianDetectField +UINT32 Oct6100ApiCheckEndianDetectField( + IN OUT tPOCTRPC_OGRDTP_HEADER f_pOgrdtpHeader, + IN UINT32 f_ulPktLengthDword ) +{ + PUINT32 pulPktPayload; + UINT32 ulBytePositionW = cOCT6100_INVALID_VALUE; + UINT32 ulBytePositionX = cOCT6100_INVALID_VALUE; + UINT32 ulBytePositionY = cOCT6100_INVALID_VALUE; + UINT32 ulBytePositionZ = cOCT6100_INVALID_VALUE; + UINT32 ulTempVar; + UINT32 i; + + /* Bytes in dword are labeled as Z Y X W. */ + + /* Only swap if necessary. */ + if ( f_pOgrdtpHeader->ulEndianDetect != cOCTRPC_ENDIAN_DETECT ) + { + /* Find the position of each byte. */ + for ( i = 0; i < 4; i++ ) + { + ulTempVar = (f_pOgrdtpHeader->ulEndianDetect >> (8 * i)) & 0xFF; + switch ( ulTempVar ) + { + case cOCTRPC_ENDIAN_DETECT_BYTE_W: + ulBytePositionW = i * 8; + break; + case cOCTRPC_ENDIAN_DETECT_BYTE_X: + ulBytePositionX = i * 8; + break; + case cOCTRPC_ENDIAN_DETECT_BYTE_Y: + ulBytePositionY = i * 8; + break; + case cOCTRPC_ENDIAN_DETECT_BYTE_Z: + ulBytePositionZ = i * 8; + break; + default: + return cOCT6100_ERR_REMOTEDEBUG_INVALID_PACKET; + } + } + + /* Make sure all bytes of the endian detect field were found. */ + if ( ulBytePositionW == cOCT6100_INVALID_VALUE || + ulBytePositionX == cOCT6100_INVALID_VALUE || + ulBytePositionY == cOCT6100_INVALID_VALUE || + ulBytePositionZ == cOCT6100_INVALID_VALUE ) + return cOCT6100_ERR_REMOTEDEBUG_INVALID_PACKET; + + /* Swap the bytes of each dword of the packet. */ + pulPktPayload = ( PUINT32 )f_pOgrdtpHeader; + for ( i = 0; i < f_ulPktLengthDword; i++ ) + { + ulTempVar = pulPktPayload[ i ]; + pulPktPayload[ i ] = ((ulTempVar >> ulBytePositionZ) & 0xFF) << 24; + pulPktPayload[ i ] |= ((ulTempVar >> ulBytePositionY) & 0xFF) << 16; + pulPktPayload[ i ] |= ((ulTempVar >> ulBytePositionX) & 0xFF) << 8; + pulPktPayload[ i ] |= ((ulTempVar >> ulBytePositionW) & 0xFF) << 0; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCalculateChecksum + +Description: Calculates the checksum of the given packet payload. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pulPktPayload Pointer to the payload of the packet. +f_ulPktLengthDword Length of the packet in dwords. +f_pulChecksum Pointer to the checksum of the packet. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCalculateChecksum +VOID Oct6100ApiCalculateChecksum( + IN PUINT32 f_pulPktPayload, + IN UINT32 f_ulPktLengthDword, + OUT PUINT32 f_pulChecksum ) +{ + tPOCTRPC_OGRDTP_HEADER pOgrdtpHeader; + UINT32 i; + + for ( i = 0, *f_pulChecksum = 0; i < f_ulPktLengthDword; i++ ) + { + *f_pulChecksum += (f_pulPktPayload[ i ] >> 16) & 0xFFFF; + *f_pulChecksum += (f_pulPktPayload[ i ] >> 0) & 0xFFFF; + } + + pOgrdtpHeader = ( tPOCTRPC_OGRDTP_HEADER )f_pulPktPayload; + *f_pulChecksum -= (pOgrdtpHeader->ulChecksum >> 16) & 0xFFFF; + *f_pulChecksum -= (pOgrdtpHeader->ulChecksum >> 0) & 0xFFFF; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiFormResponsePkt + +Description: Modifies the values of the indicated receive packet, update + the checksum field, and copy the receive packet to the + response packet. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pulRcvPktPayload Pointer to the payload of the received packet. +f_pulRspPktPayload Pointer to the payload of the response packet. +f_ulPktLengthDword Length of the packet in dwords. +f_fRetryPktResponse Flag indicating if the received packet was a retry packet. +f_fReplaceProtocolNum Flag indicating if the protocol number must be replaced. +f_fReplaceInterfaceType Flag indicating if the interface type must be replaced. +f_fReplaceInterfaceVersion Flag indicating if the interface version must be replaced. +f_ulSessionIndex Index of the remote debug session within the API' session list. +f_ulParsingErrorValue Parsing error value. +f_ulPayloadDwordIndex Index in the packet where the payload starts. +f_ulChecksum Checksum of the packet. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiFormResponsePkt +VOID Oct6100ApiFormResponsePkt( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN PUINT32 f_pulRcvPktPayload, + OUT PUINT32 f_pulRspPktPayload, + IN UINT32 f_ulPktLengthDword, + IN BOOL f_fRetryPktResponse, + IN BOOL f_fReplaceProtocolNum, + IN BOOL f_fReplaceInterfaceType, + IN BOOL f_fReplaceInterfaceVersion, + IN UINT32 f_ulSessionIndex, + IN UINT32 f_ulParsingErrorValue, + IN UINT32 f_ulPayloadDwordIndex, + IN UINT32 f_ulChecksum ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCTRPC_OGRDTP_HEADER pOgrdtpHeader; + tPOCTRPC_INTERFACE_HEADER pInterfaceHeader; + PUINT32 pulPktCache; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Typecast pointer to OGRDTP packet header. */ + pOgrdtpHeader = ( tPOCTRPC_OGRDTP_HEADER )f_pulRcvPktPayload; + + /* Check if a response to a retry packet. */ + if ( f_fRetryPktResponse == TRUE ) + { + mOCT6100_GET_REMOTE_DEBUG_SESSION_PKT_CACHE_PNT( pSharedInfo, pulPktCache, f_ulSessionIndex ) + + Oct6100UserMemCopy( f_pulRspPktPayload, pulPktCache, f_ulPktLengthDword * 4 ); + return; + } + + /* Replace all packet header fields which must be changed. */ + if ( f_ulParsingErrorValue != cOCT6100_INVALID_VALUE ) + { + f_ulChecksum -= (pOgrdtpHeader->ulParsingError >> 16) & 0xFFFF; + f_ulChecksum -= (pOgrdtpHeader->ulParsingError >> 0) & 0xFFFF; + + pOgrdtpHeader->ulParsingError = f_ulParsingErrorValue; + + f_ulChecksum += (pOgrdtpHeader->ulParsingError >> 16) & 0xFFFF; + f_ulChecksum += (pOgrdtpHeader->ulParsingError >> 0) & 0xFFFF; + } + + if ( f_fReplaceProtocolNum == TRUE ) + { + f_ulChecksum -= (pOgrdtpHeader->ulRpcProtocolNum >> 16) & 0xFFFF; + f_ulChecksum -= (pOgrdtpHeader->ulRpcProtocolNum >> 0) & 0xFFFF; + + pOgrdtpHeader->ulRpcProtocolNum = cOCTRPC_PROTOCOL_V1_1; + + f_ulChecksum += (pOgrdtpHeader->ulRpcProtocolNum >> 16) & 0xFFFF; + f_ulChecksum += (pOgrdtpHeader->ulRpcProtocolNum >> 0) & 0xFFFF; + } + + if ( f_fReplaceInterfaceType == TRUE ) + { + pInterfaceHeader = ( tPOCTRPC_INTERFACE_HEADER )(f_pulRcvPktPayload + (sizeof( tOCTRPC_OGRDTP_HEADER ) / 4)); + + f_ulChecksum -= (pInterfaceHeader->ulInterfaceType >> 16) & 0xFFFF; + f_ulChecksum -= (pInterfaceHeader->ulInterfaceType >> 0) & 0xFFFF; + + pInterfaceHeader->ulInterfaceType = cOCTRPC_OCT6100_INTERFACE; + + f_ulChecksum += (pInterfaceHeader->ulInterfaceType >> 16) & 0xFFFF; + f_ulChecksum += (pInterfaceHeader->ulInterfaceType >> 0) & 0xFFFF; + } + + if ( f_fReplaceInterfaceVersion == TRUE ) + { + pInterfaceHeader = ( tPOCTRPC_INTERFACE_HEADER )(f_pulRcvPktPayload + (sizeof( tOCTRPC_OGRDTP_HEADER ) / 4)); + + f_ulChecksum -= (pInterfaceHeader->ulInterfaceVersion >> 16) & 0xFFFF; + f_ulChecksum -= (pInterfaceHeader->ulInterfaceVersion >> 0) & 0xFFFF; + + pInterfaceHeader->ulInterfaceVersion = cOCTRPC_INTERFACE_VERSION; + + f_ulChecksum += (pInterfaceHeader->ulInterfaceVersion >> 16) & 0xFFFF; + f_ulChecksum += (pInterfaceHeader->ulInterfaceVersion >> 0) & 0xFFFF; + } + + if ( f_ulPayloadDwordIndex != cOCT6100_INVALID_VALUE ) + { + f_pulRcvPktPayload += f_ulPayloadDwordIndex; + + f_ulChecksum -= (*f_pulRcvPktPayload >> 16) & 0xFFFF; + f_ulChecksum -= (*f_pulRcvPktPayload >> 0) & 0xFFFF; + + *f_pulRcvPktPayload = cOCTRPC_UNKNOWN_COMMAND_NUM; + + f_ulChecksum += (*f_pulRcvPktPayload >> 16) & 0xFFFF; + f_ulChecksum += (*f_pulRcvPktPayload >> 0) & 0xFFFF; + + f_pulRcvPktPayload -= f_ulPayloadDwordIndex; + } + + /* Replace checksum. */ + pOgrdtpHeader->ulChecksum = f_ulChecksum; + + /* Copy the modified receive packet payload to the response packet. */ + Oct6100UserMemCopy( f_pulRspPktPayload, f_pulRcvPktPayload, f_ulPktLengthDword * 4 ); + + /* Copy the response packet to the session's packet cache. */ + if ( f_ulSessionIndex != cOCT6100_INVALID_VALUE ) + { + mOCT6100_GET_REMOTE_DEBUG_SESSION_PKT_CACHE_PNT( pSharedInfo, pulPktCache, f_ulSessionIndex ) + + Oct6100UserMemCopy( pulPktCache, f_pulRspPktPayload, f_ulPktLengthDword * 4 ); + } +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckPktCommands + +Description: Checks the commands contained in the packet for errors in size. + Also checks for unknown commands. If an error is encountered + then the function will construct the response packet. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pulRcvPktPayload Pointer to the payload of the received packet. +f_pulRspPktPayload Pointer to the payload of the response packet. +f_ulPktLengthDword Length of the packet in dwords. +f_ulSessionIndex Index of the remote debug session within the API' session list. +f_ulChecksum Checksum of the packet. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckPktCommands +UINT32 Oct6100ApiCheckPktCommands( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN PUINT32 f_pulRcvPktPayload, + IN OUT PUINT32 f_pulRspPktPayload, + IN UINT32 f_ulSessionIndex, + IN UINT32 f_ulPktLengthDword, + IN UINT32 f_ulChecksum ) +{ + tPOCTRPC_COMMAND_HEADER pCmndHeader; + UINT32 ulNumDwordsLeft; + UINT32 ulNumDwordsNeeded = 0; + UINT32 ulRpcCmndSizeDword; + BOOL fCmndIdentified; + BOOL fCmndHeaderPresent; + + pCmndHeader = ( tPOCTRPC_COMMAND_HEADER )(f_pulRcvPktPayload + ((sizeof( tOCTRPC_OGRDTP_HEADER ) + sizeof( tOCTRPC_INTERFACE_HEADER )) / 4)); + ulNumDwordsLeft = f_ulPktLengthDword - ((sizeof( tOCTRPC_OGRDTP_HEADER ) + sizeof( tOCTRPC_INTERFACE_HEADER )) / 4); + ulRpcCmndSizeDword = sizeof( tOCTRPC_COMMAND_HEADER ) / 4; + fCmndIdentified = TRUE; + + while ( ulNumDwordsLeft != 0 ) + { + if ( ulNumDwordsLeft < ulRpcCmndSizeDword ) + { + fCmndHeaderPresent = FALSE; + } + else + { + fCmndHeaderPresent = TRUE; + + switch ( pCmndHeader->ulRpcCommandNum ) + { + case cOCT6100_RPC_READ_WORD: + { + ulNumDwordsNeeded = sizeof( tOCT6100_RPC_READ_WORD ) / 4; + } + break; + case cOCT6100_RPC_READ_BURST: + { + tPOCT6100_RPC_READ_BURST pBurstHeader; + + ulNumDwordsNeeded = (sizeof( tOCT6100_RPC_READ_BURST ) - sizeof( UINT32 )) / 4; + pBurstHeader = ( tPOCT6100_RPC_READ_BURST )(( PUINT32 )pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + ulNumDwordsNeeded += (pBurstHeader->ulBurstLength + 1) / 2; + } + break; + case cOCT6100_RPC_WRITE_WORD: + { + ulNumDwordsNeeded = sizeof( tOCT6100_RPC_WRITE_WORD ) / 4; + } + break; + case cOCT6100_RPC_WRITE_SMEAR: + { + ulNumDwordsNeeded = sizeof( tOCT6100_RPC_WRITE_SMEAR ) / 4; + } + break; + case cOCT6100_RPC_WRITE_INC: + { + ulNumDwordsNeeded = sizeof( tOCT6100_RPC_WRITE_INC ) / 4; + } + break; + case cOCT6100_RPC_READ_ARRAY: + { + tPOCT6100_RPC_READ_ARRAY pArrayHeader; + + ulNumDwordsNeeded = (sizeof( tOCT6100_RPC_READ_ARRAY ) - sizeof( UINT32 )) / 4; + pArrayHeader = ( tPOCT6100_RPC_READ_ARRAY )(( PUINT32 )pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + ulNumDwordsNeeded += pArrayHeader->ulArrayLength; + ulNumDwordsNeeded += (pArrayHeader->ulArrayLength + 1) / 2; + } + break; + case cOCT6100_RPC_WRITE_BURST: + { + tPOCT6100_RPC_WRITE_BURST pBurstHeader; + + ulNumDwordsNeeded = (sizeof( tOCT6100_RPC_WRITE_BURST ) - sizeof( UINT32 )) / 4; + pBurstHeader = ( tPOCT6100_RPC_WRITE_BURST )(( PUINT32 )pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + ulNumDwordsNeeded += (pBurstHeader->ulBurstLength + 1) / 2; + } + break; + case cOCT6100_RPC_SET_HOT_CHANNEL: + { + ulNumDwordsNeeded = sizeof( tOCT6100_RPC_SET_HOT_CHANNEL ) / 4; + } + break; + case cOCT6100_RPC_GET_DEBUG_CHAN_INDEX: + { + ulNumDwordsNeeded = sizeof( tOCT6100_RPC_GET_DEBUG_CHAN_INDEX ) / 4; + } + break; + case cOCT6100_RPC_API_DISCONNECT: + { + /* There is no parameter to the disconnect command. */ + ulNumDwordsNeeded = 0; + } + break; + default: + fCmndIdentified = FALSE; + } + + ulNumDwordsNeeded += sizeof( tOCTRPC_COMMAND_HEADER ) / 4; + } + + if ( fCmndHeaderPresent != TRUE ) + { + Oct6100ApiFormResponsePkt( f_pApiInstance, f_pulRcvPktPayload, f_pulRspPktPayload, f_ulPktLengthDword, FALSE, FALSE, FALSE, FALSE, f_ulSessionIndex, cOCTRPC_RDBGERR_INVALID_PACKET_LENGTH, cOCT6100_INVALID_VALUE, f_ulChecksum ); + return cOCT6100_ERR_REMOTE_DEBUG_PARSING_ERROR; + } + if ( fCmndIdentified != TRUE ) + { + Oct6100ApiFormResponsePkt( f_pApiInstance, f_pulRcvPktPayload, f_pulRspPktPayload, f_ulPktLengthDword, FALSE, FALSE, FALSE, FALSE, f_ulSessionIndex, cOCTRPC_RDBGERR_INVALID_COMMAND_NUMBER, f_ulPktLengthDword - ulNumDwordsLeft, f_ulChecksum ); + return cOCT6100_ERR_REMOTE_DEBUG_PARSING_ERROR; + } + + if ( ulNumDwordsNeeded != (pCmndHeader->ulCommandByteSize / 4) || + ulNumDwordsNeeded > ulNumDwordsLeft ) + { + Oct6100ApiFormResponsePkt( f_pApiInstance, f_pulRcvPktPayload, f_pulRspPktPayload, f_ulPktLengthDword, FALSE, FALSE, FALSE, FALSE, f_ulSessionIndex, cOCTRPC_RDBGERR_INVALID_COMMAND_LENGTH, cOCT6100_INVALID_VALUE, f_ulChecksum ); + return cOCT6100_ERR_REMOTE_DEBUG_PARSING_ERROR; + } + + pCmndHeader = ( tPOCTRPC_COMMAND_HEADER )(( PUINT32 )pCmndHeader + ulNumDwordsNeeded); + ulNumDwordsLeft -= ulNumDwordsNeeded; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiExecutePktCommands + +Description: Executes the commands contained in the received packet. The + received packet payload buffer is modified but NOT copied to + the response packet buffer. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pulRcvPktPayload Pointer to the payload of the received packet. +f_ulPktLengthDword Length of the packet in dwords. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiExecutePktCommands +VOID Oct6100ApiExecutePktCommands( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN PUINT32 f_pulRcvPktPayload, + IN UINT32 f_ulPktLengthDword ) +{ + tPOCTRPC_COMMAND_HEADER pReqCmndHeader; + tPOCTRPC_OGRDTP_HEADER pReqPktHeader; + UINT32 ulNumDwordsLeft; + UINT32 ulRpcCmndSizeDword; + + pReqPktHeader = ( tPOCTRPC_OGRDTP_HEADER )(f_pulRcvPktPayload); + pReqCmndHeader = ( tPOCTRPC_COMMAND_HEADER )(( PUINT32 )f_pulRcvPktPayload + ((sizeof( tOCTRPC_OGRDTP_HEADER ) + sizeof( tOCTRPC_INTERFACE_HEADER )) / 4)); + ulNumDwordsLeft = f_ulPktLengthDword - ((sizeof( tOCTRPC_OGRDTP_HEADER ) + sizeof( tOCTRPC_INTERFACE_HEADER )) / 4); + ulRpcCmndSizeDword = sizeof( tOCTRPC_COMMAND_HEADER ) / 4; + + while ( ulNumDwordsLeft != 0 ) + { + /* Switch on command number. */ + switch ( pReqCmndHeader->ulRpcCommandNum ) + { + case cOCT6100_RPC_READ_WORD: + Oct6100ApiRpcReadWord( f_pApiInstance, pReqCmndHeader ); + break; + case cOCT6100_RPC_READ_BURST: + Oct6100ApiRpcReadBurst( f_pApiInstance, pReqCmndHeader ); + break; + case cOCT6100_RPC_READ_ARRAY: + Oct6100ApiRpcReadArray( f_pApiInstance, pReqCmndHeader ); + break; + case cOCT6100_RPC_WRITE_WORD: + Oct6100ApiRpcWriteWord( f_pApiInstance, pReqCmndHeader ); + break; + case cOCT6100_RPC_WRITE_SMEAR: + Oct6100ApiRpcWriteSmear( f_pApiInstance, pReqCmndHeader ); + break; + case cOCT6100_RPC_WRITE_BURST: + Oct6100ApiRpcWriteBurst( f_pApiInstance, pReqCmndHeader ); + break; + case cOCT6100_RPC_SET_HOT_CHANNEL: + Oct6100ApiRpcSetHotChannel( f_pApiInstance, pReqCmndHeader ); + break; + case cOCT6100_RPC_GET_DEBUG_CHAN_INDEX: + Oct6100ApiRpcGetDebugChanIndex( f_pApiInstance, pReqCmndHeader ); + break; + case cOCT6100_RPC_API_DISCONNECT: + Oct6100ApiRpcDisconnect( f_pApiInstance, pReqCmndHeader, pReqPktHeader->ulDebugSessionNum ); + break; + default: + pReqCmndHeader->ulFunctionResult = cOCT6100_ERR_REMOTEDEBUG_INVALID_RPC_COMMAND_NUM; + break; + } + + /* Insert the result of the operation in the command header. */ + if ( pReqCmndHeader->ulFunctionResult != cOCT6100_ERR_OK ) + break; + + /* Decrement the number of DWORDs left in the packet. */ + ulNumDwordsLeft -= pReqCmndHeader->ulCommandByteSize / 4; + + /* Point to the next command in the packet. */ + pReqCmndHeader = ( tPOCTRPC_COMMAND_HEADER )(( PUINT32 )pReqCmndHeader + (pReqCmndHeader->ulCommandByteSize / 4)); + } +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckSessionNum + +Description: Checks if there is a session list entry open for the session + number received. If not, a free one is reserved if one is + available. If none are free, one which has timed-out is + released. If none are timed out then an error is returned. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pOgrdtpHeader Pointer to the header of the packet. +f_pulSessionIndex Pointer to the remote debugging session within the + API's session list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckSessionNum +UINT32 Oct6100ApiCheckSessionNum( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCTRPC_OGRDTP_HEADER f_pOgrdtpHeader, + OUT PUINT32 f_pulSessionIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_REMOTE_DEBUG_INFO pRemoteDebugInfo; + tPOCT6100_API_REMOTE_DEBUG_SESSION pSessionEntry; + tPOCT6100_API_REMOTE_DEBUG_SESSION pSessionLink; + tOCT6100_GET_TIME GetTime; + PVOID pSessionTree; + PUINT32 pulTreeData; + UINT32 ulNewSessionIndex; + UINT32 aulTimeDiff[ 2 ]; + UINT32 ulResult; + UINT16 usNegative; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context of GetTime. */ + GetTime.pProcessContext = f_pApiInstance->pProcessContext; + + /* Get the current system time. */ + ulResult = Oct6100UserGetTime( &GetTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Get a local pointer to the remote debugging info. */ + pRemoteDebugInfo = &pSharedInfo->RemoteDebugInfo; + + /* Check if the session number has an associated session list entry. */ + mOCT6100_GET_REMOTE_DEBUG_TREE_PNT( pSharedInfo, pSessionTree ) + + ulResult = octapi_bt0_query_node( pSessionTree, ( ( PVOID )(&f_pOgrdtpHeader->ulDebugSessionNum) ), ( ( PVOID* )&pulTreeData ) ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Return session index. */ + *f_pulSessionIndex = *pulTreeData; + + /* A session list entry is associated, so update the entries last packet time, + transaction number and packet retry number, and position in the linked list. */ + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, *pulTreeData, pSessionEntry ) + + pSessionEntry->aulLastPktTime[ 0 ] = GetTime.aulWallTimeUs[ 0 ]; + pSessionEntry->aulLastPktTime[ 1 ] = GetTime.aulWallTimeUs[ 1 ]; + pSessionEntry->ulPktRetryNum = f_pOgrdtpHeader->ulPktRetryNum; + + /* Remove the node from its current place in the linked-list and add it to the end. */ + if ( pRemoteDebugInfo->ulSessionListTail != *pulTreeData ) + { + /* Obtain local pointer to the session list entry to be moved. */ + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, *pulTreeData, pSessionEntry ) + + /* Update link of previous session in list. */ + if ( pSessionEntry->ulBackwardLink != cOCT6100_INVALID_VALUE ) + { + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, pSessionEntry->ulBackwardLink, pSessionLink ) + pSessionLink->ulForwardLink = pSessionEntry->ulForwardLink; + } + else + { + pRemoteDebugInfo->ulSessionListHead = pSessionEntry->ulForwardLink; + } + + /* Update link of next session in list. */ + if ( pSessionEntry->ulForwardLink != cOCT6100_INVALID_VALUE ) + { + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, pSessionEntry->ulForwardLink, pSessionLink ) + pSessionLink->ulBackwardLink = pSessionEntry->ulBackwardLink; + } + else + { + pRemoteDebugInfo->ulSessionListTail = pSessionEntry->ulBackwardLink; + } + + /* Place session at the end of the list. */ + pSessionEntry->ulBackwardLink = pRemoteDebugInfo->ulSessionListTail; + pSessionEntry->ulForwardLink = cOCT6100_INVALID_VALUE; + + pRemoteDebugInfo->ulSessionListTail = *pulTreeData; + + if ( pRemoteDebugInfo->ulSessionListHead == cOCT6100_INVALID_VALUE ) + { + pRemoteDebugInfo->ulSessionListHead = *pulTreeData; + } + else + { + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, pSessionEntry->ulBackwardLink, pSessionLink ) + pSessionLink->ulForwardLink = *pulTreeData; + } + } + + /* Check if packet should be interpreted based on transaction number. */ + if ( f_pOgrdtpHeader->ulPktRetryNum != 0 && + pSessionEntry->ulTransactionNum == f_pOgrdtpHeader->ulTransactionNum && + pSessionEntry->ulPktByteSize == f_pOgrdtpHeader->ulPktByteSize ) + return cOCT6100_ERR_REMOTEDEBUG_TRANSACTION_ANSWERED; + + /* Update transaction number since packet will be interpreted. */ + pSessionEntry->ulTransactionNum = f_pOgrdtpHeader->ulTransactionNum; + pSessionEntry->ulPktByteSize = f_pOgrdtpHeader->ulPktByteSize; + + return cOCT6100_ERR_OK; + } + else if ( ulResult == OCTAPI_BT0_KEY_NOT_IN_TREE ) + { + /* If there is a free entry in the session list then seize it. Else, try to + find an entry which has timed out. If there are none then return an error. */ + if ( pRemoteDebugInfo->ulNumSessionsOpen < pRemoteDebugInfo->ulMaxSessionsOpen ) + { + ulNewSessionIndex = pRemoteDebugInfo->ulNumSessionsOpen; + } + else /* ( pRemoteDebugInfo->ulNumSessionsOpen == pRemoteDebugInfo->ulMaxSessionsOpen ) */ + { + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, pRemoteDebugInfo->ulSessionListHead, pSessionEntry ) + + ulResult = octapi_lm_subtract( GetTime.aulWallTimeUs, 1, pSessionEntry->aulLastPktTime, 1, aulTimeDiff, 1, &usNegative ); + if ( ulResult != cOCT6100_ERR_OK || usNegative != FALSE ) + return cOCT6100_ERR_FATAL_43; + + /* If there are no session list entries available then return the packet with + a parsing error. */ + if ( aulTimeDiff[ 1 ] == 0 && aulTimeDiff[ 0 ] < (cOCTRPC_SESSION_TIMEOUT * 1000000) ) + return cOCT6100_ERR_REMOTEDEBUG_ALL_SESSIONS_OPEN; + + ulNewSessionIndex = pRemoteDebugInfo->ulSessionListHead; + + /* Remove old session index. */ + ulResult = octapi_bt0_remove_node( pSessionTree, ( ( PVOID )&pSessionEntry->ulSessionNum ) ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_44; + + if ( pSessionEntry->ulBackwardLink != cOCT6100_INVALID_VALUE ) + { + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, pSessionEntry->ulBackwardLink, pSessionLink ) + pSessionLink->ulForwardLink = pSessionEntry->ulForwardLink; + } + else + { + pRemoteDebugInfo->ulSessionListHead = pSessionEntry->ulForwardLink; + } + + if ( pSessionEntry->ulForwardLink != cOCT6100_INVALID_VALUE ) + { + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, pSessionEntry->ulForwardLink, pSessionLink ) + pSessionLink->ulBackwardLink = pSessionEntry->ulBackwardLink; + } + else + { + pRemoteDebugInfo->ulSessionListTail = pSessionEntry->ulBackwardLink; + } + + /* Decrement number of open sessions. */ + pRemoteDebugInfo->ulNumSessionsOpen--; + } + + /* Add new session. */ + ulResult = octapi_bt0_add_node( pSessionTree, ( ( PVOID )&f_pOgrdtpHeader->ulDebugSessionNum ), ( ( PVOID* )&pulTreeData ) ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_45; + *pulTreeData = ulNewSessionIndex; + + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, ulNewSessionIndex, pSessionEntry ) + + pSessionEntry->aulLastPktTime[ 0 ] = GetTime.aulWallTimeUs[ 0 ]; + pSessionEntry->aulLastPktTime[ 1 ] = GetTime.aulWallTimeUs[ 1 ]; + pSessionEntry->ulSessionNum = f_pOgrdtpHeader->ulDebugSessionNum; + pSessionEntry->ulTransactionNum = f_pOgrdtpHeader->ulTransactionNum; + pSessionEntry->ulPktRetryNum = f_pOgrdtpHeader->ulPktRetryNum; + + pSessionEntry->ulBackwardLink = pRemoteDebugInfo->ulSessionListTail; + pSessionEntry->ulForwardLink = cOCT6100_INVALID_VALUE; + + pRemoteDebugInfo->ulSessionListTail = ulNewSessionIndex; + if ( pRemoteDebugInfo->ulSessionListHead == cOCT6100_INVALID_VALUE ) + pRemoteDebugInfo->ulSessionListHead = ulNewSessionIndex; + + if ( pSessionEntry->ulBackwardLink != cOCT6100_INVALID_VALUE ) + { + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, pSessionEntry->ulBackwardLink, pSessionLink ) + pSessionLink->ulForwardLink = ulNewSessionIndex; + } + + *f_pulSessionIndex = ulNewSessionIndex; + + /* Increment number of open sessions. */ + pRemoteDebugInfo->ulNumSessionsOpen++; + + return cOCT6100_ERR_OK; + } + else + { + return cOCT6100_ERR_FATAL_46; + } +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRpcReadWord + +Description: Checks the provided portion of an OCTRPC packet and interprets + it as an cOCT6100_RPC_READ_WORD command. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pCmndHeader Pointer to RPC command structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRpcReadWord +VOID Oct6100ApiRpcReadWord( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ) +{ + tPOCT6100_RPC_READ_WORD pReadCommand; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT16 usReadData; + + /* Get pointer to command arguments. */ + pReadCommand = ( tPOCT6100_RPC_READ_WORD )(( PUINT32 )f_pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + + /* Set some read structure parameters. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Copy parameters from packet payload to local read structure. */ + ReadParams.ulReadAddress = pReadCommand->ulAddress; + + /* Supply memory for read data. */ + ReadParams.pusReadData = &usReadData; + + /* Perform read access. */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + + usReadData &= 0xFFFF; + + /* Return read data and result. */ + pReadCommand->ulReadData = (usReadData << 16) | usReadData; + f_pCmndHeader->ulFunctionResult = ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRpcReadBurst + +Description: Checks the provided portion of an OCTRPC packet and interprets + it as an cOCT6100_RPC_READ_BURST command. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pCmndHeader Pointer to RPC command structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRpcReadBurst +VOID Oct6100ApiRpcReadBurst( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ) +{ + tPOCT6100_RPC_READ_BURST pBurstCommand; + tOCT6100_READ_BURST_PARAMS BurstParams; + UINT32 ulResult = cOCT6100_ERR_OK; + UINT32 ulTempVar; + UINT32 i; + PUINT16 pusReadData; + UINT32 ulNumWordsToRead; + + /* Get local pointer to remote debugging read data buffer. */ + mOCT6100_GET_REMOTE_DEBUG_DATA_BUF_PNT( f_pApiInstance->pSharedInfo, pusReadData ) + + /* Get pointer to command arguments. */ + pBurstCommand = ( tPOCT6100_RPC_READ_BURST )(( PUINT32 )f_pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + + /* Set some read structure parameters. */ + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Copy parameters from packet payload to local read structure. */ + BurstParams.ulReadAddress = pBurstCommand->ulAddress; + + + /* Supply memory for read data. */ + BurstParams.pusReadData = pusReadData; + + ulNumWordsToRead = pBurstCommand->ulBurstLength; + while( ulNumWordsToRead > 0) + { + if ( ulNumWordsToRead <= f_pApiInstance->pSharedInfo->ChipConfig.usMaxRwAccesses ) + BurstParams.ulReadLength = ulNumWordsToRead; + else + BurstParams.ulReadLength = f_pApiInstance->pSharedInfo->ChipConfig.usMaxRwAccesses; + + /* Perform read access. */ + mOCT6100_DRIVER_READ_BURST_API( BurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + { + f_pCmndHeader->ulFunctionResult = ulResult; + return; + } + + BurstParams.ulReadAddress += BurstParams.ulReadLength * 2; + BurstParams.pusReadData += BurstParams.ulReadLength; + + /* Update the number of dword to read. */ + ulNumWordsToRead -= BurstParams.ulReadLength; + } + + /* Return read data. */ + ulTempVar = (pBurstCommand->ulBurstLength + 1) / 2; + for ( i = 0; i < ulTempVar; i++ ) + { + pBurstCommand->aulReadData[ i ] = (*pusReadData & 0xFFFF) << 16; + pusReadData++; + pBurstCommand->aulReadData[ i ] |= (*pusReadData & 0xFFFF) << 0; + pusReadData++; + } + + /* Return result. */ + f_pCmndHeader->ulFunctionResult = ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRpcReadArray + +Description: Checks the provided portion of an OCTRPC packet and interprets + it as an cOCT6100_RPC_READ_ARRAY command. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pCmndHeader Pointer to RPC command structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRpcReadArray +VOID Oct6100ApiRpcReadArray( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ) +{ + tPOCT6100_RPC_READ_ARRAY pArrayCommand; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult = cOCT6100_ERR_OK; + UINT32 i; + PUINT32 pulAddressArray; + PUINT32 pulDataArray; + UINT16 usReadData; + + + /* Get pointer to command arguments. */ + pArrayCommand = ( tPOCT6100_RPC_READ_ARRAY )(( PUINT32 )f_pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + + /* Set some read structure parameters. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Supply memory for read data. */ + ReadParams.pusReadData = &usReadData; + + /* Get pointers to array of addresses and data. */ + pulAddressArray = pArrayCommand->aulArrayData; + pulDataArray = pArrayCommand->aulArrayData + pArrayCommand->ulArrayLength; + + for ( i = 0; i < pArrayCommand->ulArrayLength; i++ ) + { + /* Copy parameters from packet payload to local read structure. */ + ReadParams.ulReadAddress = pulAddressArray[ i ]; + + /* Perform read access. */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + break; + + /* Return read data. */ + if ( (i % 2) == 0 ) + pulDataArray[ i / 2 ] = (usReadData & 0xFFFF) << 16; + else /* ( (i % 2) == 1 ) */ + pulDataArray[ i / 2 ] |= (usReadData & 0xFFFF) << 0; + } + + /* Return result. */ + f_pCmndHeader->ulFunctionResult = ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRpcWriteWord + +Description: Checks the provided portion of an OCTRPC packet and interprets + it as an cOCT6100_RPC_WRITE_WORD command. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pCmndHeader Pointer to RPC command structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRpcWriteWord +VOID Oct6100ApiRpcWriteWord( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ) +{ + tPOCT6100_RPC_WRITE_WORD pWriteCommand; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Get pointer to command arguments. */ + pWriteCommand = ( tPOCT6100_RPC_WRITE_WORD )(( PUINT32 )f_pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + + /* Set some read structure parameters. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Copy parameters from packet payload to local read structure. */ + WriteParams.ulWriteAddress = pWriteCommand->ulAddress; + WriteParams.usWriteData = (UINT16)pWriteCommand->ulWriteData; + + /* Perform write access. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + + /* Return result. */ + f_pCmndHeader->ulFunctionResult = ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRpcWriteSmear + +Description: Checks the provided portion of an OCTRPC packet and interprets + it as an cOCT6100_RPC_WRITE_SMEAR command. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pCmndHeader Pointer to RPC command structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRpcWriteSmear +VOID Oct6100ApiRpcWriteSmear( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ) +{ + tPOCT6100_RPC_WRITE_SMEAR pSmearCommand; + tOCT6100_WRITE_SMEAR_PARAMS SmearParams; + UINT32 ulResult; + + /* Get pointer to command arguments. */ + pSmearCommand = ( tPOCT6100_RPC_WRITE_SMEAR )(( PUINT32 )f_pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + + /* Set the smear structure parameters. */ + SmearParams.pProcessContext = f_pApiInstance->pProcessContext; + + SmearParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Copy parameters from packet payload to local read structure. */ + SmearParams.ulWriteAddress = pSmearCommand->ulAddress; + SmearParams.usWriteData = (UINT16)pSmearCommand->ulWriteData; + SmearParams.ulWriteLength = pSmearCommand->ulSmearLength; + + /* Perform write access. */ + mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ) + + /* Return result. */ + f_pCmndHeader->ulFunctionResult = ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRpcWriteBurst + +Description: Checks the provided portion of an OCTRPC packet and interprets + it as an cOCT6100_RPC_WRITE_BURST command. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pCmndHeader Pointer to RPC command structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRpcWriteBurst +VOID Oct6100ApiRpcWriteBurst( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ) +{ + tPOCT6100_RPC_WRITE_BURST pBurstCommand; + tOCT6100_WRITE_BURST_PARAMS BurstParams; + UINT32 ulResult; + UINT32 ulTempVar; + UINT32 i, j; + PUINT16 pusWriteData; + + /* Get local pointer to remote debugging write data buffer. */ + mOCT6100_GET_REMOTE_DEBUG_DATA_BUF_PNT( f_pApiInstance->pSharedInfo, pusWriteData ) + + /* Get pointer to command arguments. */ + pBurstCommand = ( tPOCT6100_RPC_WRITE_BURST )(( PUINT32 )f_pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + + ulTempVar = (pBurstCommand->ulBurstLength + 1) / 2; + for ( i = 0, j = 0; i < ulTempVar; i++ ) + { + pusWriteData[ j++ ] = (UINT16)((pBurstCommand->aulWriteData[ i ] >> 16) & 0xFFFF); + pusWriteData[ j++ ] = (UINT16)((pBurstCommand->aulWriteData[ i ] >> 0) & 0xFFFF); + } + + /* Set some structure parameters. */ + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Copy parameters from packet payload to local read structure. */ + BurstParams.ulWriteAddress = pBurstCommand->ulAddress; + BurstParams.ulWriteLength = pBurstCommand->ulBurstLength; + BurstParams.pusWriteData = pusWriteData; + + /* Perform write access. */ + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ) + + /* Return result. */ + f_pCmndHeader->ulFunctionResult = ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRpcSetHotChannel + +Description: Checks the provided portion of an OCTRPC packet and interprets + it as an cOCT6100_RPC_SET_HOT_CHANNEL command. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pCmndHeader Pointer to RPC command structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRpcSetHotChannel +VOID Oct6100ApiRpcSetHotChannel( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ) +{ + tPOCT6100_RPC_SET_HOT_CHANNEL pHotChanCommand; + tOCT6100_DEBUG_SELECT_CHANNEL DebugSelectChannel; + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulResult; + + pHotChanCommand = ( tPOCT6100_RPC_SET_HOT_CHANNEL )(( PUINT32 )f_pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + + /* Verify if the hot channel index is valid. */ + if ( pHotChanCommand->ulHotChannel >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + { + f_pCmndHeader->ulFunctionResult = cOCT6100_ERR_REMOTEDEBUG_INVALID_HOT_CHAN_INDEX; + return; + } + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, pHotChanCommand->ulHotChannel ); + + DebugSelectChannel.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | (pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | pHotChanCommand->ulHotChannel; + + /* The PCM law parameter is now obsolete. */ + /* The instance knows the law of the channel being recorded! */ + + /* Call the function. */ + ulResult = Oct6100DebugSelectChannelSer( f_pApiInstance, &DebugSelectChannel, FALSE ); + + /* Return result. */ + f_pCmndHeader->ulFunctionResult = ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRpcGetDebugChanIndex + +Description: Checks the provided portion of an OCTRPC packet and interprets + it as an cOCT6100_RPC_GET_DEBUG_CHAN_INDEX command. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pCmndHeader Pointer to RPC command structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRpcGetDebugChanIndex +VOID Oct6100ApiRpcGetDebugChanIndex( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ) +{ + tPOCT6100_RPC_GET_DEBUG_CHAN_INDEX pDebugChanCommand; + + pDebugChanCommand = ( tPOCT6100_RPC_GET_DEBUG_CHAN_INDEX )(( PUINT32 )f_pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + + /* Set the debug channel index of the structure. */ + pDebugChanCommand->ulDebugChanIndex = f_pApiInstance->pSharedInfo->DebugInfo.usRecordMemIndex; + + /* Return result. */ + f_pCmndHeader->ulFunctionResult = cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRpcDisconnect + +Description: Destroy the current session. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pCmndHeader Pointer to RPC command structure. +f_ulSessionNumber Session number of the current remote debugging session. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRpcDisconnect +VOID Oct6100ApiRpcDisconnect( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader, + IN UINT32 f_ulSessionNumber ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_REMOTE_DEBUG_INFO pRemoteDebugInfo; + tPOCT6100_API_REMOTE_DEBUG_SESSION pSessionEntry; + tPOCT6100_API_REMOTE_DEBUG_SESSION pSessionTempEntry; + PVOID pSessionTree; + UINT32 ulResult; + PUINT32 pulTreeData; + UINT32 ulSessionIndex; + + f_pCmndHeader->ulFunctionResult = cOCT6100_ERR_OK; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get a local pointer to the remote debugging info. */ + pRemoteDebugInfo = &pSharedInfo->RemoteDebugInfo; + + /* Check if the session number has an associated session list entry. */ + mOCT6100_GET_REMOTE_DEBUG_TREE_PNT( pSharedInfo, pSessionTree ) + + ulResult = octapi_bt0_query_node( pSessionTree, ( ( PVOID )(&f_ulSessionNumber) ), ( ( PVOID* )&pulTreeData ) ); + if ( ulResult != cOCT6100_ERR_OK ) + f_pCmndHeader->ulFunctionResult = cOCT6100_ERR_REMOTEDEBUG_INAVLID_SESSION_NUMBER; + + /* Return session index. */ + ulSessionIndex= *pulTreeData; + + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, ulSessionIndex, pSessionEntry ); + + /* Clear the entry of the session. */ + pSessionEntry->aulLastPktTime[ 0 ] = 0; + pSessionEntry->aulLastPktTime[ 1 ] = 0; + pSessionEntry->ulSessionNum = cOCT6100_INVALID_VALUE; + pSessionEntry->ulTransactionNum = cOCT6100_INVALID_VALUE; + pSessionEntry->ulPktRetryNum = cOCT6100_INVALID_VALUE; + + /* Update the other entry before removing the node. */ + pSessionEntry->ulBackwardLink = pRemoteDebugInfo->ulSessionListTail; + pSessionEntry->ulForwardLink = cOCT6100_INVALID_VALUE; + + if ( pSessionEntry->ulBackwardLink != cOCT6100_INVALID_VALUE ) + { + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, pSessionEntry->ulBackwardLink, pSessionTempEntry ); + pSessionTempEntry->ulForwardLink = pSessionEntry->ulForwardLink; + } + else /* pSessionEntry->ulBackwardLink == cOCT6100_INVALID_VALUE */ + { + pRemoteDebugInfo->ulSessionListHead = pSessionEntry->ulForwardLink; + } + + if ( pSessionEntry->ulForwardLink != cOCT6100_INVALID_VALUE ) + { + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, pSessionEntry->ulForwardLink, pSessionTempEntry ); + pSessionTempEntry->ulBackwardLink = pSessionEntry->ulBackwardLink; + } + else /* pSessionEntry->ulForwardLink == cOCT6100_INVALID_VALUE */ + { + pRemoteDebugInfo->ulSessionListTail = pSessionEntry->ulBackwardLink; + } + + /* Invalidate the pointer. */ + pSessionEntry->ulBackwardLink = cOCT6100_INVALID_VALUE; + pSessionEntry->ulForwardLink = cOCT6100_INVALID_VALUE; + + /* Remove the session. */ + ulResult = octapi_bt0_remove_node( pSessionTree, ( ( PVOID )&f_ulSessionNumber ) ); + if ( ulResult != cOCT6100_ERR_OK ) + f_pCmndHeader->ulFunctionResult = cOCT6100_ERR_FATAL_47; + + /* Increment number of open sessions. */ + pRemoteDebugInfo->ulNumSessionsOpen--; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tlv.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tlv.c new file mode 100644 index 0000000..ab2dd70 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tlv.c @@ -0,0 +1,2056 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tlv.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the functions used to read information allowing the + API to know where all the features supported by this API version are + located in the chip's external memory. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 113 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" + +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" + +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_inst.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_tlv_priv.h" + +/**************************** PRIVATE FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiProcessTlvRegion + +Description: This function will read and interpret the TLV memory of the chip + to obtain memory offsets and features available of the image + loaded into the chip. + + The API will read this region until it finds a TLV type of 0 with + a length of 0. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiProcessTlvRegion +UINT32 Oct6100ApiProcessTlvRegion( + tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_READ_PARAMS ReadParams; + UINT16 usReadData; + UINT32 ulResult; + + UINT32 ulTlvTypeField; + UINT32 ulTlvLengthField; + UINT32 ulTlvWritingTimeoutCount = 0; + UINT32 ulConditionFlag = TRUE; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Set the address of the first TLV type. */ + ReadParams.ulReadAddress = cOCT6100_TLV_BASE; + ReadParams.ulReadAddress += 2; + + /* Wait for the TLV configuration to be configured in memory. */ + while ( ulConditionFlag ) + { + /* Read the TLV write done flag. */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData & 0x1 ) + break; + + ulTlvWritingTimeoutCount++; + if ( ulTlvWritingTimeoutCount == 0x100000 ) + return cOCT6100_ERR_TLV_TIMEOUT; + } + + /*======================================================================*/ + /* Read the first 16 bits of the TLV type. */ + + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulTlvTypeField = usReadData << 16; + + /* Read the last word of the TLV type. */ + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulTlvTypeField |= usReadData; + + /*======================================================================*/ + + + /*======================================================================*/ + /* Now, read the TLV field length. */ + + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulTlvLengthField = usReadData << 16; + + /* Read the last word of the TLV length. */ + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulTlvLengthField |= usReadData; + + /* Modify the address to point at the TLV value field. */ + ReadParams.ulReadAddress += 2; + + /*======================================================================*/ + + /* Read the TLV value until the end of TLV region is reached. */ + while( !((ulTlvTypeField == 0) && (ulTlvLengthField == 0)) ) + { + ulResult = Oct6100ApiInterpretTlvEntry( f_pApiInstance, + ulTlvTypeField, + ulTlvLengthField, + ReadParams.ulReadAddress ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the address to after the TLV value. */ + ReadParams.ulReadAddress += ulTlvLengthField; + + /*======================================================================*/ + /* Read the first 16 bits of the TLV type. */ + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulTlvTypeField = usReadData << 16; + + /* Read the last word of the TLV type. */ + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulTlvTypeField |= usReadData; + + /*======================================================================*/ + + + /*======================================================================*/ + /* Now, read the TLV field length. */ + + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulTlvLengthField = usReadData << 16; + + /* Read the last word of the TLV length. */ + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulTlvLengthField |= usReadData; + + ReadParams.ulReadAddress += 2; + + /*======================================================================*/ + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInterpretTlvEntry + +Description: This function will interpret a TLV entry from the chip. All + known TLV types by the API are exhaustively listed here. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulTlvFieldType Type of the TLV field to interpret. +f_ulTlvFieldLength Byte length of the TLV field. +f_ulTlvValueAddress Address where the data of the TLV block starts. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInterpretTlvEntry +UINT32 Oct6100ApiInterpretTlvEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulTlvFieldType, + IN UINT32 f_ulTlvFieldLength, + IN UINT32 f_ulTlvValueAddress ) +{ + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult = cOCT6100_ERR_OK; + UINT16 usReadData; + UINT32 i; + UINT32 ulTempValue = 0; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Find out how to interpret the TLV value according to the TLV type. */ + switch( f_ulTlvFieldType ) + { + case cOCT6100_TLV_TYPE_VERSION_NUMBER: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_VERSION_NUMBER, + cOCT6100_TLV_MAX_LENGTH_VERSION_NUMBER ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ReadParams.ulReadAddress = f_ulTlvValueAddress; + + for( i = 0; i < (f_ulTlvFieldLength/2); i++ ) + { + /* Perform the actual read. */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + f_pApiInstance->pSharedInfo->ImageInfo.szVersionNumber[ (i * 2) ] = (UINT8)((usReadData >> 8) & 0xFF); + f_pApiInstance->pSharedInfo->ImageInfo.szVersionNumber[ (i * 2) + 1 ] = (UINT8)((usReadData >> 0) & 0xFF); + + /* Modify the address. */ + ReadParams.ulReadAddress += 2; + } + } + break; + + case cOCT6100_TLV_TYPE_CUSTOMER_PROJECT_ID: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CUSTOMER_PROJECT_ID, + cOCT6100_TLV_MAX_LENGTH_CUSTOMER_PROJECT_ID ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Perform the actual read. */ + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->ImageInfo.ulBuildId ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_CH0_MAIN_BASE_ADDRESS: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CH0_MAIN_BASE_ADDRESS, + cOCT6100_TLV_MAX_LENGTH_CH0_MAIN_BASE_ADDRESS ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemBase ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemBase &= 0x0FFFFFFF; + + /* Modify the base address to incorporate the external memory offset. */ + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemBase += cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + } + break; + + case cOCT6100_TLV_TYPE_CH_MAIN_SIZE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CH_MAIN_SIZE, + cOCT6100_TLV_MAX_LENGTH_CH_MAIN_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_CH_MAIN_IO_OFFSET: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CH_MAIN_IO_OFFSET, + cOCT6100_TLV_MAX_LENGTH_CH_MAIN_IO_OFFSET ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_CH_MAIN_ZCB_OFFSET: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CH_MAIN_ZCB_OFFSET, + cOCT6100_TLV_MAX_LENGTH_CH_MAIN_ZCB_OFFSET ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainRinCBMemOfst ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_CH_MAIN_ZCB_SIZE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CH_MAIN_ZCB_SIZE, + cOCT6100_TLV_MAX_LENGTH_CH_MAIN_ZCB_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainRinCBMemSize ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_CH_MAIN_XCB_OFFSET: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CH_MAIN_XCB_OFFSET, + cOCT6100_TLV_MAX_LENGTH_CH_MAIN_XCB_OFFSET ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainSinCBMemOfst ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_CH_MAIN_XCB_SIZE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CH_MAIN_XCB_SIZE, + cOCT6100_TLV_MAX_LENGTH_CH_MAIN_XCB_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainSinCBMemSize ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_CH_MAIN_YCB_OFFSET: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CH_MAIN_YCB_OFFSET, + cOCT6100_TLV_MAX_LENGTH_CH_MAIN_YCB_OFFSET ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainSoutCBMemOfst ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_CH_MAIN_YCB_SIZE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CH_MAIN_YCB_SIZE, + cOCT6100_TLV_MAX_LENGTH_CH_MAIN_YCB_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainSoutCBMemSize ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_FREE_MEM_BASE_ADDRESS: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_FREE_MEM_BASE_ADDRESS, + cOCT6100_TLV_MAX_LENGTH_FREE_MEM_BASE_ADDRESS ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulFreeMemBaseAddress ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + f_pApiInstance->pSharedInfo->MemoryMap.ulFreeMemBaseAddress &= 0x0FFFFFFF; + + } + break; + + case cOCT6100_TLV_TYPE_CHAN_MAIN_IO_STATS_OFFSET: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CHAN_MAIN_IO_STATS_OFFSET, + cOCT6100_TLV_MAX_LENGTH_CHAN_MAIN_IO_STATS_OFFSET ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoStatsOfst ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_CHAN_MAIN_IO_STATS_SIZE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CHAN_MAIN_IO_STATS_OFFSET, + cOCT6100_TLV_MAX_LENGTH_CHAN_MAIN_IO_STATS_OFFSET ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoStatsSize ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_CH_ROOT_CONF_OFFSET: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CH_ROOT_CONF_OFFSET, + cOCT6100_TLV_MAX_LENGTH_CH_ROOT_CONF_OFFSET ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanRootConfOfst ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + + case cOCT6100_TLV_TYPE_POA_CH_MAIN_ZPO_OFFSET: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_CH_MAIN_ZPO_OFFSET, + cOCT6100_TLV_MAX_LENGTH_POA_CH_MAIN_ZPO_OFFSET ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainRinPlayoutMemOfst ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_POA_CH_MAIN_ZPO_SIZE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_CH_MAIN_ZPO_SIZE, + cOCT6100_TLV_MAX_LENGTH_POA_CH_MAIN_ZPO_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainRinPlayoutMemSize ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_POA_CH_MAIN_YPO_OFFSET: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_CH_MAIN_YPO_OFFSET, + cOCT6100_TLV_MAX_LENGTH_POA_CH_MAIN_YPO_OFFSET ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainSoutPlayoutMemOfst ); + } + break; + + case cOCT6100_TLV_TYPE_POA_CH_MAIN_YPO_SIZE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_CH_MAIN_YPO_SIZE, + cOCT6100_TLV_MAX_LENGTH_POA_CH_MAIN_YPO_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainSoutPlayoutMemSize ); + } + break; + + case cOCT6100_TLV_TYPE_POA_BOFF_RW_ZWP: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_ZWP, + cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_ZWP ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst ); + } + break; + + case cOCT6100_TLV_TYPE_POA_BOFF_RW_ZIS: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_ZIS, + cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_ZIS ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PlayoutRinIgnoreSkipCleanOfst ); + } + break; + + case cOCT6100_TLV_TYPE_POA_BOFF_RW_ZSP: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_ZSP, + cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_ZSP ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PlayoutRinSkipPtrOfst ); + } + break; + + case cOCT6100_TLV_TYPE_POA_BOFF_RW_YWP: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_YWP, + cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_YWP ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst ); + } + break; + + case cOCT6100_TLV_TYPE_POA_BOFF_RW_YIS: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_YIS, + cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_YIS ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PlayoutSoutIgnoreSkipCleanOfst ); + } + break; + + case cOCT6100_TLV_TYPE_POA_BOFF_RW_YSP: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_YSP, + cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_YSP ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PlayoutSoutSkipPtrOfst ); + } + break; + + case cOCT6100_TLV_TYPE_POA_BOFF_RO_ZRP: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RO_ZRP, + cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RO_ZRP ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst ); + } + break; + + case cOCT6100_TLV_TYPE_POA_BOFF_RO_YRP: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RO_YRP, + cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RO_YRP ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst ); + } + break; + + case cOCT6100_TLV_TYPE_CNR_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CNR_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_CNR_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ConferencingNoiseReductionOfst ); + } + break; + + case cOCT6100_TLV_TYPE_ANR_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_ANR_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_ANR_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.AdaptiveNoiseReductionOfst ); + } + break; + + case cOCT6100_TLV_TYPE_HZ_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_HZ_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_HZ_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.RinDcOffsetRemovalOfst ); + } + /* Set flag indicating that the feature is present.*/ + f_pApiInstance->pSharedInfo->ImageInfo.fRinDcOffsetRemoval = TRUE; + break; + + case cOCT6100_TLV_TYPE_HX_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_HX_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_HX_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.SinDcOffsetRemovalOfst ); + } + /* Set flag indicating that the feature is present.*/ + f_pApiInstance->pSharedInfo->ImageInfo.fSinDcOffsetRemoval = TRUE; + break; + + case cOCT6100_TLV_TYPE_LCA_Z_CONF_BOFF_RW_GAIN: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_LCA_Z_CONF_BOFF_RW_GAIN, + cOCT6100_TLV_MAX_LENGTH_LCA_Z_CONF_BOFF_RW_GAIN ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.RinLevelControlOfst ); + } + break; + + case cOCT6100_TLV_TYPE_LCA_Y_CONF_BOFF_RW_GAIN: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_LCA_Y_CONF_BOFF_RW_GAIN, + cOCT6100_TLV_MAX_LENGTH_LCA_Y_CONF_BOFF_RW_GAIN ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.SoutLevelControlOfst ); + } + break; + + case cOCT6100_TLV_TYPE_CNA_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CNA_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_CNA_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ComfortNoiseModeOfst ); + } + /* Set flag indicating that the feature is present.*/ + f_pApiInstance->pSharedInfo->ImageInfo.fComfortNoise = TRUE; + break; + + case cOCT6100_TLV_TYPE_NOA_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_NOA_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_NOA_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.NlpControlFieldOfst ); + } + /* Set flag indicating that the feature is present.*/ + f_pApiInstance->pSharedInfo->ImageInfo.fNlpControl = TRUE; + break; + + case cOCT6100_TLV_TYPE_VFA_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_VFA_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_VFA_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.VadControlFieldOfst ); + } + /* Set flag indicating that the feature is present.*/ + f_pApiInstance->pSharedInfo->ImageInfo.fSilenceSuppression = TRUE; + break; + + case cOCT6100_TLV_TYPE_TLA_MAIN_IO_BOFF_RW_TAIL_DISP: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_TLA_MAIN_IO_BOFF_RW_TAIL_DISP, + cOCT6100_TLV_MAX_LENGTH_TLA_MAIN_IO_BOFF_RW_TAIL_DISP ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PouchTailDisplOfst ); + } + break; + + case cOCT6100_TLV_TYPE_BOOTA_POUCH_BOFF_RW_BOOT_INST: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_BOOTA_POUCH_BOFF_RW_BOOT_INST, + cOCT6100_TLV_MAX_LENGTH_BOOTA_POUCH_BOFF_RW_BOOT_INST ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PouchBootInstructionOfst ); + } + break; + + case cOCT6100_TLV_TYPE_BOOTA_POUCH_BOFF_RW_BOOT_RESULT: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_BOOTA_POUCH_BOFF_RW_BOOT_RESULT, + cOCT6100_TLV_MAX_LENGTH_BOOTA_POUCH_BOFF_RW_BOOT_RESULT ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PouchBootResultOfst ); + } + break; + + case cOCT6100_TLV_TYPE_TDM_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_TDM_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_TDM_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ToneDisablerControlOfst ); + } + + f_pApiInstance->pSharedInfo->ImageInfo.fToneDisabler = TRUE; + break; + + case cOCT6100_TLV_TYPE_DIS_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_DIS_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_DIS_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.TailDisplEnableOfst ); + } + + f_pApiInstance->pSharedInfo->ImageInfo.fTailDisplacement = TRUE; + break; + + case cOCT6100_TLV_TYPE_NT_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_NT_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_NT_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.NlpTrivialFieldOfst ); + } + + break; + + case cOCT6100_TLV_TYPE_DEBUG_CHAN_INDEX_VALUE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_DEBUG_CHAN_INDEX_VALUE, + cOCT6100_TLV_MAX_LENGTH_DEBUG_CHAN_INDEX_VALUE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + } + + f_pApiInstance->pSharedInfo->DebugInfo.usRecordMemIndex = (UINT16)( ulTempValue & 0xFFFF ); + + break; + + case cOCT6100_TLV_TYPE_ADPCM_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_ADPCM_ENABLE, + cOCT6100_TLV_MAX_LENGTH_ADPCM_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + } + + if ( ulTempValue == 0 ) + f_pApiInstance->pSharedInfo->ImageInfo.fAdpcm = FALSE; + else + f_pApiInstance->pSharedInfo->ImageInfo.fAdpcm = TRUE; + + break; + + case cOCT6100_TLV_TYPE_CONFERENCING_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CONFERENCING_ENABLE, + cOCT6100_TLV_MAX_LENGTH_CONFERENCING_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + } + + if ( ulTempValue == 0 ) + f_pApiInstance->pSharedInfo->ImageInfo.fConferencing = FALSE; + else + f_pApiInstance->pSharedInfo->ImageInfo.fConferencing = TRUE; + + break; + + case cOCT6100_TLV_TYPE_TONE_DETECTOR_PROFILE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_TONE_DETECTOR_PROFILE, + cOCT6100_TLV_MIN_LENGTH_TONE_DETECTOR_PROFILE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->ImageInfo.ulToneProfileNumber ); + } + + break; + + case cOCT6100_TLV_TYPE_MAX_TAIL_DISPLACEMENT: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_MAX_TAIL_DISPLACEMENT, + cOCT6100_TLV_MAX_LENGTH_MAX_TAIL_DISPLACEMENT ); + if ( ulResult == cOCT6100_ERR_OK ) + { + UINT32 ulTailDispTempValue; + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTailDispTempValue ); + + ulTailDispTempValue += 1; /* Convert the value into milliseconds.*/ + ulTailDispTempValue *= 16; /* value was given in multiple of 16 ms. */ + + if ( ulTailDispTempValue >= 128 ) + f_pApiInstance->pSharedInfo->ImageInfo.usMaxTailDisplacement = (UINT16)( ulTailDispTempValue - 128 ); + else + f_pApiInstance->pSharedInfo->ImageInfo.usMaxTailDisplacement = 0; + + } + + break; + + case cOCT6100_TLV_TYPE_AEC_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_AEC_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_AEC_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.AecFieldOfst ); + } + + /* Set the flag. */ + f_pApiInstance->pSharedInfo->ImageInfo.fAecEnabled = TRUE; + + /* Acoustic echo cancellation available! */ + f_pApiInstance->pSharedInfo->ImageInfo.fAcousticEcho = TRUE; + + break; + + case cOCT6100_TLV_TYPE_PCM_LEAK_CONF_BOFF_RW: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_PCM_LEAK_CONF_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_PCM_LEAK_CONF_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PcmLeakFieldOfst ); + } + + f_pApiInstance->pSharedInfo->ImageInfo.fNonLinearityBehaviorA = TRUE; + break; + + case cOCT6100_TLV_TYPE_DEFAULT_ERL_CONF_BOFF_RW: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_DEFAULT_ERL_CONF_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_DEFAULT_ERL_CONF_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.DefaultErlFieldOfst ); + } + + /* Set the flag. */ + f_pApiInstance->pSharedInfo->ImageInfo.fDefaultErl = TRUE; + + break; + + case cOCT6100_TLV_TYPE_TONE_REM_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_TONE_REM_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_TONE_REM_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ToneRemovalFieldOfst ); + } + + /* Set the flag. */ + f_pApiInstance->pSharedInfo->ImageInfo.fToneRemoval = TRUE; + + break; + + + + case cOCT6100_TLV_TYPE_TLA_MAIN_IO_BOFF_RW_MAX_ECHO_POINT: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_TLA_MAIN_IO_BOFF_RW_MAX_ECHO_POINT, + cOCT6100_TLV_MAX_LENGTH_TLA_MAIN_IO_BOFF_RW_MAX_ECHO_POINT ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ChanMainIoMaxEchoPointOfst ); + } + + /* Set the flag. */ + f_pApiInstance->pSharedInfo->ImageInfo.fMaxEchoPoint = TRUE; + + break; + + case cOCT6100_TLV_TYPE_NLP_CONV_CAP_CONF_BOFF_RW: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_NLP_CONV_CAP_CONF_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_NLP_CONV_CAP_CONF_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.NlpConvCapFieldOfst ); + } + + /* Set the flag. */ + f_pApiInstance->pSharedInfo->ImageInfo.fNonLinearityBehaviorB = TRUE; + + break; + + case cOCT6100_TLV_TYPE_MATRIX_EVENT_SIZE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_MATRIX_EVENT_SIZE, + cOCT6100_TLV_MAX_LENGTH_MATRIX_EVENT_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->DebugInfo.ulDebugEventSize ); + } + + break; + + case cOCT6100_TLV_TYPE_CNR_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CNR_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_CNR_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + f_pApiInstance->pSharedInfo->ImageInfo.fConferencingNoiseReduction = (UINT8)( ulTempValue & 0xFF ); + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fConferencingNoiseReduction == TRUE ) + { + /* Set flag indicating that the dominant speaker feature is present. */ + f_pApiInstance->pSharedInfo->ImageInfo.fDominantSpeakerEnabled = TRUE; + } + } + + break; + + case cOCT6100_TLV_TYPE_MAX_TAIL_LENGTH_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_MAX_TAIL_LENGTH_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_MAX_TAIL_LENGTH_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + f_pApiInstance->pSharedInfo->ImageInfo.usMaxTailLength = (UINT16)( ulTempValue & 0xFFFF ); + } + + break; + + case cOCT6100_TLV_TYPE_MAX_NUMBER_OF_CHANNELS: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_MAX_NUMBER_OF_CHANNELS, + cOCT6100_TLV_MAX_LENGTH_MAX_NUMBER_OF_CHANNELS ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + f_pApiInstance->pSharedInfo->ImageInfo.usMaxNumberOfChannels = (UINT16)( ulTempValue & 0xFFFF ); + } + + break; + + case cOCT6100_TLV_TYPE_PLAYOUT_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_PLAYOUT_ENABLE, + cOCT6100_TLV_MAX_LENGTH_PLAYOUT_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Set flag indicating that the feature is present. */ + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + f_pApiInstance->pSharedInfo->ImageInfo.fBufferPlayout = (UINT8)( ulTempValue & 0xFF ); + } + + break; + + case cOCT6100_TLV_TYPE_DOMINANT_SPEAKER_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_DOMINANT_SPEAKER_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_DOMINANT_SPEAKER_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.DominantSpeakerFieldOfst ); + } + + break; + + case cOCT6100_TLV_TYPE_TAIL_DISP_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_TAIL_DISP_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_TAIL_DISP_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PerChanTailDisplacementFieldOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fPerChannelTailDisplacement = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_ANR_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_ANR_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_ANR_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + f_pApiInstance->pSharedInfo->ImageInfo.fAdaptiveNoiseReduction = (UINT8)( ulTempValue & 0xFF ); + } + + break; + + case cOCT6100_TLV_TYPE_MUSIC_PROTECTION_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_MUSIC_PROTECTION_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_MUSIC_PROTECTION_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + f_pApiInstance->pSharedInfo->ImageInfo.fMusicProtection = (UINT8)( ulTempValue & 0xFF ); + } + + break; + + case cOCT6100_TLV_TYPE_AEC_DEFAULT_ERL_BOFF: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_AEC_DEFAULT_ERL_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_AEC_DEFAULT_ERL_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.AecDefaultErlFieldOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fAecDefaultErl = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_Z_ALC_TARGET_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_Z_ALC_TARGET_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_Z_ALC_TARGET_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.RinAutoLevelControlTargetOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fRinAutoLevelControl = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_Y_ALC_TARGET_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_Y_ALC_TARGET_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_Y_ALC_TARGET_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.SoutAutoLevelControlTargetOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fSoutAutoLevelControl = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_Z_HLC_TARGET_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_Z_HLC_TARGET_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_Z_HLC_TARGET_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.RinHighLevelCompensationThresholdOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fRinHighLevelCompensation = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_Y_HLC_TARGET_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_Y_HLC_TARGET_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_Y_HLC_TARGET_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.SoutHighLevelCompensationThresholdOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fSoutHighLevelCompensation = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_ALC_HLC_STATUS_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_ALC_HLC_STATUS_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_ALC_HLC_STATUS_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.AlcHlcStatusOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fAlcHlcStatus = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_Z_PLAYOUT_HARD_SKIP_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_Z_PLAYOUT_HARD_SKIP_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_Z_PLAYOUT_HARD_SKIP_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PlayoutRinHardSkipOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_Y_PLAYOUT_HARD_SKIP_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_Y_PLAYOUT_HARD_SKIP_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_Y_PLAYOUT_HARD_SKIP_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PlayoutSoutHardSkipOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_AFT_FIELD_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_AFT_FIELD_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_AFT_FIELD_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.AftControlOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fAftControl = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_VOICE_DETECTED_STAT_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_VOICE_DETECTED_STAT_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_VOICE_DETECTED_STAT_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.SinVoiceDetectedStatOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fSinVoiceDetectedStat = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_GAIN_APPLIED_RIN_STAT_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_GAIN_APPLIED_RIN_STAT_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_GAIN_APPLIED_RIN_STAT_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.RinAppliedGainStatOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fRinAppliedGainStat = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_GAIN_APPLIED_SOUT_STAT_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_GAIN_APPLIED_SOUT_STAT_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_GAIN_APPLIED_SOUT_STAT_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.SoutAppliedGainStatOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fSoutAppliedGainStat = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_MAX_ADAPT_ALE_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_MAX_ADAPT_ALE_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_MAX_ADAPT_ALE_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.AdaptiveAleOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fListenerEnhancement = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_RIN_ANR_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_RIN_ANR_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_RIN_ANR_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.RinAnrOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fRoutNoiseReduction = TRUE; + } + + break; + case cOCT6100_TLV_TYPE_RIN_ANR_VALUE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_RIN_ANR_VALUE_RW, + cOCT6100_TLV_MAX_LENGTH_RIN_ANR_VALUE_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.RinAnrValOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fRoutNoiseReductionLevel = TRUE; + } + + break; + case cOCT6100_TLV_TYPE_RIN_MUTE_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_RIN_MUTE_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_RIN_MUTE_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.RinMuteOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fRinMute = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_SIN_MUTE_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_SIN_MUTE_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_SIN_MUTE_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.SinMuteOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fSinMute = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_NUMBER_PLAYOUT_EVENTS: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_NUMBER_PLAYOUT_EVENTS, + cOCT6100_TLV_MAX_LENGTH_NUMBER_PLAYOUT_EVENTS ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + f_pApiInstance->pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents = (UINT8)( ulTempValue & 0xFF ); + } + + break; + + case cOCT6100_TLV_TYPE_ANR_SNR_IMPROVEMENT_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_ANR_SNR_IMPROVEMENT_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_ANR_SNR_IMPROVEMENT_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.AnrSnrEnhancementOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fAnrSnrEnhancement = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_ANR_AGRESSIVITY_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_ANR_AGRESSIVITY_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_ANR_AGRESSIVITY_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.AnrVoiceNoiseSegregationOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fAnrVoiceNoiseSegregation = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_CHAN_TAIL_LENGTH_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CHAN_TAIL_LENGTH_BOFF, + cOCT6100_TLV_MAX_LENGTH_CHAN_TAIL_LENGTH_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PerChanTailLengthFieldOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fPerChannelTailLength = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_CHAN_VQE_TONE_DISABLING_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CHAN_VQE_TONE_DIS_BOFF, + cOCT6100_TLV_MAX_LENGTH_CHAN_VQE_TONE_DIS_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ToneDisablerVqeActivationDelayOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fToneDisablerVqeActivationDelay = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_AF_TAIL_DISP_VALUE_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_AF_TAIL_DISP_VALUE_BOFF, + cOCT6100_TLV_MAX_LENGTH_AF_TAIL_DISP_VALUE_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.AfTailDisplacementFieldOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fAfTailDisplacement = TRUE; + } + + break; + + + case cOCT6100_TLV_TYPE_POUCH_COUNTER_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POUCH_COUNTER_BOFF, + cOCT6100_TLV_MAX_LENGTH_POUCH_COUNTER_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PouchCounterFieldOfst ); + + f_pApiInstance->pSharedInfo->DebugInfo.fPouchCounter = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_AEC_TAIL_LENGTH_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_AEC_TAIL_BOFF, + cOCT6100_TLV_MAX_LENGTH_AEC_TAIL_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.AecTailLengthFieldOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fAecTailLength = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_MATRIX_DWORD_BASE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_MATRIX_DWORD_BASE, + cOCT6100_TLV_MAX_LENGTH_MATRIX_DWORD_BASE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->DebugInfo.ulMatrixBaseAddress ); + + /* Mask the upper bits set by the firmware. */ + f_pApiInstance->pSharedInfo->DebugInfo.ulMatrixBaseAddress &= 0x0FFFFFFF; + + /* Modify the base address to incorporate the external memory offset. */ + f_pApiInstance->pSharedInfo->DebugInfo.ulMatrixBaseAddress += cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + } + + break; + + case cOCT6100_TLV_TYPE_DEBUG_CHAN_STATS_BYTE_SIZE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_DEBUG_CHAN_STATS_BYTE_SIZE, + cOCT6100_TLV_MAX_LENGTH_DEBUG_CHAN_STATS_BYTE_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->DebugInfo.ulDebugChanStatsByteSize ); + } + + break; + + case cOCT6100_TLV_TYPE_DEBUG_CHAN_LITE_STATS_BYTE_SIZE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_DEBUG_CHAN_LITE_STATS_BYTE_SIZE, + cOCT6100_TLV_MAX_LENGTH_DEBUG_CHAN_LITE_STATS_BYTE_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->DebugInfo.ulDebugChanLiteStatsByteSize ); + } + + break; + + case cOCT6100_TLV_TYPE_HOT_CHANNEL_SELECT_DWORD_BASE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_HOT_CHANNEL_SELECT_DWORD_BASE, + cOCT6100_TLV_MAX_LENGTH_HOT_CHANNEL_SELECT_DWORD_BASE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->DebugInfo.ulHotChannelSelectBaseAddress ); + } + + break; + + case cOCT6100_TLV_TYPE_MATRIX_TIMESTAMP_DWORD_BASE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_TIMESTAMP_DWORD_BASE, + cOCT6100_TLV_MAX_LENGTH_TIMESTAMP_DWORD_BASE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->DebugInfo.ulMatrixTimestampBaseAddress ); + } + + break; + + case cOCT6100_TLV_TYPE_MATRIX_WP_DWORD_BASE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_MATRIX_WP_DWORD_BASE, + cOCT6100_TLV_MAX_LENGTH_MATRIX_WP_DWORD_BASE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->DebugInfo.ulMatrixWpBaseAddress ); + } + + break; + + case cOCT6100_TLV_TYPE_AF_WRITE_PTR_BYTE_OFFSET: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_AF_WRITE_PTR_BYTE_OFFSET, + cOCT6100_TLV_MAX_LENGTH_AF_WRITE_PTR_BYTE_OFFSET ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->DebugInfo.ulAfWritePtrByteOffset ); + } + + break; + + case cOCT6100_TLV_TYPE_RECORDED_PCM_EVENT_BYTE_SIZE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_RECORDED_PCM_EVENT_BYTE_SIZE, + cOCT6100_TLV_MAX_LENGTH_RECORDED_PCM_EVENT_BYTE_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize ); + } + + break; + + case cOCT6100_TLV_TYPE_IS_ISR_CALLED_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_IS_ISR_CALLED_BOFF, + cOCT6100_TLV_MAX_LENGTH_IS_ISR_CALLED_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.IsIsrCalledFieldOfst ); + + f_pApiInstance->pSharedInfo->DebugInfo.fIsIsrCalledField = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_MUSIC_PROTECTION_ENABLE_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_MUSIC_PROTECTION_ENABLE_BOFF, + cOCT6100_TLV_MAX_LENGTH_MUSIC_PROTECTION_ENABLE_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.MusicProtectionFieldOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fMusicProtectionConfiguration = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_IDLE_CODE_DETECTION_ENABLE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_IDLE_CODE_DETECTION, + cOCT6100_TLV_MAX_LENGTH_IDLE_CODE_DETECTION ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + f_pApiInstance->pSharedInfo->ImageInfo.fIdleCodeDetection = (UINT8)( ulTempValue & 0xFF ); + } + + break; + + case cOCT6100_TLV_TYPE_IDLE_CODE_DETECTION_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_IDLE_CODE_DETECTION_BOFF, + cOCT6100_TLV_MAX_LENGTH_IDLE_CODE_DETECTION_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.IdleCodeDetectionFieldOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fIdleCodeDetectionConfiguration = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_IMAGE_TYPE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_IMAGE_TYPE, + cOCT6100_TLV_MAX_LENGTH_IMAGE_TYPE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + /* Check if read image type value is what's expected. */ + if ( ( ulTempValue != cOCT6100_IMAGE_TYPE_WIRELINE ) + && ( ulTempValue != cOCT6100_IMAGE_TYPE_COMBINED ) ) + return cOCT6100_ERR_FATAL_E9; + + f_pApiInstance->pSharedInfo->ImageInfo.byImageType = (UINT8)( ulTempValue & 0xFF ); + } + + break; + + case cOCT6100_TLV_TYPE_MAX_WIRELINE_CHANNELS: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_MAX_WIRELINE_CHANNELS, + cOCT6100_TLV_MAX_LENGTH_MAX_WIRELINE_CHANNELS ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + } + + break; + + case cOCT6100_TLV_TYPE_AF_EVENT_CB_SIZE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_AF_EVENT_CB_BYTE_SIZE, + cOCT6100_TLV_MAX_LENGTH_AF_EVENT_CB_BYTE_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->DebugInfo.ulAfEventCbByteSize ); + } + + break; + + case cOCT6100_TLV_TYPE_BUFFER_PLAYOUT_SKIP_IN_EVENTS: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_BUFFER_PLAYOUT_SKIP_IN_EVENTS, + cOCT6100_TLV_MAX_LENGTH_BUFFER_PLAYOUT_SKIP_IN_EVENTS ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + f_pApiInstance->pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_ZZ_ENERGY_CHAN_STATS_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_ZZ_ENERGY_CHAN_STATS_BOFF, + cOCT6100_TLV_MAX_LENGTH_ZZ_ENERGY_CHAN_STATS_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.RinEnergyStatFieldOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fRinEnergyStat = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_YY_ENERGY_CHAN_STATS_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_YY_ENERGY_CHAN_STATS_BOFF, + cOCT6100_TLV_MAX_LENGTH_YY_ENERGY_CHAN_STATS_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.SoutEnergyStatFieldOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fSoutEnergyStat = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_DOUBLE_TALK_BEH_MODE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_DOUBLE_TALK_BEH_MODE, + cOCT6100_TLV_MAX_LENGTH_DOUBLE_TALK_BEH_MODE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + if ( ulTempValue != 0 ) + f_pApiInstance->pSharedInfo->ImageInfo.fDoubleTalkBehavior = TRUE; + else + f_pApiInstance->pSharedInfo->ImageInfo.fDoubleTalkBehavior = FALSE; + + } + + break; + + case cOCT6100_TLV_TYPE_DOUBLE_TALK_BEH_MODE_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_DOUBLE_TALK_BEH_MODE_BOFF, + cOCT6100_TLV_MAX_LENGTH_DOUBLE_TALK_BEH_MODE_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.DoubleTalkBehaviorFieldOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fDoubleTalkBehaviorFieldOfst = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_SOUT_NOISE_BLEACHING: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_SOUT_NOISE_BLEACHING, + cOCT6100_TLV_MAX_LENGTH_SOUT_NOISE_BLEACHING ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + if ( ulTempValue != 0 ) + f_pApiInstance->pSharedInfo->ImageInfo.fSoutNoiseBleaching = TRUE; + else + f_pApiInstance->pSharedInfo->ImageInfo.fSoutNoiseBleaching = FALSE; + + } + + break; + + case cOCT6100_TLV_TYPE_NLP_STATISTICS: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_NLP_STATISTICS, + cOCT6100_TLV_MAX_LENGTH_NLP_STATISTICS ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + if ( ulTempValue != 0 ) + f_pApiInstance->pSharedInfo->ImageInfo.fSinLevel = TRUE; + else + f_pApiInstance->pSharedInfo->ImageInfo.fSinLevel = FALSE; + + } + + break; + + default: + /* Unknown TLV type field... check default length and nothing else. */ + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_DEFAULT, + cOCT6100_TLV_MAX_LENGTH_DEFAULT ); + break; + } + + return ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiTlvCheckLengthField + +Description: This function validates the TLV length field. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_ulTlvFieldLength Length field read from the TLV. +f_ulMinLengthValue Minimum value supported for the TLV. +f_ulMaxLengthValue Maximum value supported for the TLV. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiTlvCheckLengthField +UINT32 Oct6100ApiTlvCheckLengthField( + IN UINT32 f_ulTlvFieldLength, + IN UINT32 f_ulMinLengthValue, + IN UINT32 f_ulMaxLengthValue ) +{ + /* Check if the value is too small. */ + if ( f_ulTlvFieldLength < f_ulMinLengthValue ) + return ( cOCT6100_ERR_FATAL_59 ); + + /* Check if the value is too big. */ + if ( f_ulTlvFieldLength > f_ulMaxLengthValue ) + return ( cOCT6100_ERR_FATAL_5A ); + + /* Check if the value is dword aligned. */ + if ( ( f_ulTlvFieldLength % 4 ) != 0 ) + return ( cOCT6100_ERR_OPEN_INVALID_TLV_LENGTH ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiTlvReadBitOffsetStruct + +Description: This function extracts a bit offset structure from the TLV. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulAddress Address where the read the TLV information. +f_pBitOffsetStruct Pointer to a bit offset stucture. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiTlvReadBitOffsetStruct +UINT32 Oct6100ApiTlvReadBitOffsetStruct( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulAddress, + OUT tPOCT6100_TLV_OFFSET f_pBitOffsetStruct ) +{ + tOCT6100_READ_PARAMS ReadParams; + UINT16 usReadData; + + UINT32 ulResult; + UINT32 ulOffsetValue; + UINT32 ulSizeValue; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /*======================================================================*/ + /* Read the first 16 bits of the TLV field. */ + + ReadParams.ulReadAddress = f_ulAddress; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulOffsetValue = usReadData << 16; + + /* Read the last word of the TLV type. */ + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulOffsetValue |= usReadData; + + /*======================================================================*/ + + + /*======================================================================*/ + /* Read the first 16 bits of the TLV field. */ + + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulSizeValue = usReadData << 16; + + /* Read the last word of the TLV type. */ + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulSizeValue |= usReadData; + + /*======================================================================*/ + + /* Set the structure fields. */ + f_pBitOffsetStruct->usDwordOffset = (UINT16)(ulOffsetValue / 32); + f_pBitOffsetStruct->byBitOffset = (UINT8) (32 - (ulOffsetValue % 32) - ulSizeValue); + f_pBitOffsetStruct->byFieldSize = (UINT8) (ulSizeValue); + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tone_detection.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tone_detection.c new file mode 100644 index 0000000..6d9c82b --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tone_detection.c @@ -0,0 +1,1088 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tone_detection.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains functions used to enable and disable tone detection on + an echo channel. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 51 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_tone_detection_inst.h" +#include "oct6100api/oct6100_events_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_tone_detection_pub.h" +#include "oct6100api/oct6100_events_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_tone_detection_priv.h" +#include "oct6100_events_priv.h" + + +/**************************** PUBLIC FUNCTIONS *****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ToneDetectionEnable + +Description: This function enables the generation of event for a selected + tone on the specified channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pToneDetectEnable Pointer to tone detection enable structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ToneDetectionEnableDef +UINT32 Oct6100ToneDetectionEnableDef( + tPOCT6100_TONE_DETECTION_ENABLE f_pToneDetectEnable ) +{ + f_pToneDetectEnable->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pToneDetectEnable->ulToneNumber = cOCT6100_INVALID_TONE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ToneDetectionEnable +UINT32 Oct6100ToneDetectionEnable( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_TONE_DETECTION_ENABLE f_pToneDetectEnable ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ToneDetectionEnableSer( f_pApiInstance, f_pToneDetectEnable ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ToneDetectionDisable + +Description: This function disables the detection of a tone for a specific + channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pToneDetectDisable Pointer to tone detection disable structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ToneDetectionDisableDef +UINT32 Oct6100ToneDetectionDisableDef( + tPOCT6100_TONE_DETECTION_DISABLE f_pToneDetectDisable ) +{ + f_pToneDetectDisable->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pToneDetectDisable->ulToneNumber = cOCT6100_INVALID_VALUE; + f_pToneDetectDisable->fDisableAll = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ToneDetectionDisable +UINT32 Oct6100ToneDetectionDisable( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_TONE_DETECTION_DISABLE f_pToneDetectDisable ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ToneDetectionDisableSer( f_pApiInstance, f_pToneDetectDisable ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ToneDetectionEnableSer + +Description: Activate the detection of a tone on the specified channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pToneDetectEnable Pointer to tone detect enable structure. This structure + contains, among other things, the tone ID to enable + and the channel handle where detection should be + enabled. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ToneDetectionEnableSer +UINT32 Oct6100ToneDetectionEnableSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TONE_DETECTION_ENABLE f_pToneDetectEnable ) +{ + UINT32 ulChanIndex; + UINT32 ulExtToneChanIndex; + UINT32 ulToneEventNumber = 0; + + UINT32 ulResult; + + /* Check the user's configuration of the tone detection for errors. */ + ulResult = Oct6100ApiCheckToneEnableParams( + f_pApiInstance, + f_pToneDetectEnable, + &ulChanIndex, + &ulToneEventNumber, + + &ulExtToneChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write to all resources needed to enable tone detection. */ + ulResult = Oct6100ApiWriteToneDetectEvent( + f_pApiInstance, + ulChanIndex, + ulToneEventNumber, + + ulExtToneChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the channel entry to indicate that a new tone has been activated. */ + ulResult = Oct6100ApiUpdateChanToneDetectEntry( + f_pApiInstance, + ulChanIndex, + ulToneEventNumber, + ulExtToneChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckToneEnableParams + +Description: Check the validity of the channel and tone requested. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pToneDetectEnable Pointer to tone detection enable structure. +f_pulChannelIndex Pointer to the channel index. +f_pulToneEventNumber Pointer to the Index of the tone associated to the requested tone. +f_pulExtToneChanIndex Pointer to the index of the extended channel index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckToneEnableParams +UINT32 Oct6100ApiCheckToneEnableParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TONE_DETECTION_ENABLE f_pToneDetectEnable, + OUT PUINT32 f_pulChannelIndex, + OUT PUINT32 f_pulToneEventNumber, + + OUT PUINT32 f_pulExtToneChanIndex ) +{ + tPOCT6100_API_CHANNEL pEchoChannel; + UINT32 ulEntryOpenCnt; + UINT32 i; + + /*=====================================================================*/ + /* Check the channel handle. */ + + if ( (f_pToneDetectEnable->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_TONE_DETECTION_CHANNEL_HANDLE_INVALID; + + *f_pulChannelIndex = f_pToneDetectEnable->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK; + if ( *f_pulChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_TONE_DETECTION_CHANNEL_HANDLE_INVALID; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChannel, *f_pulChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pToneDetectEnable->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChannel->fReserved != TRUE ) + return cOCT6100_ERR_TONE_DETECTION_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChannel->byEntryOpenCnt ) + return cOCT6100_ERR_TONE_DETECTION_CHANNEL_HANDLE_INVALID; + + /* Set the extended tone detection info if it is activated on the channel. */ + *f_pulExtToneChanIndex = pEchoChannel->usExtToneChanIndex; + + /*=====================================================================*/ + /* Check the tone information. */ + + /* Find out if the tone is present in the build. */ + for ( i = 0; i < cOCT6100_MAX_TONE_EVENT; i++ ) + { + if ( f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ i ].ulToneID == f_pToneDetectEnable->ulToneNumber ) + { + *f_pulToneEventNumber = i; + break; + } + } + + /* Check if tone is present. */ + if ( i == cOCT6100_MAX_TONE_EVENT ) + return cOCT6100_ERR_NOT_SUPPORTED_TONE_NOT_PRESENT_IN_FIRMWARE; + + /* Check if the requested tone is actually detected. */ + if ((( pEchoChannel->aulToneConf[ *f_pulToneEventNumber / 32 ] >> ( 31 - ( *f_pulToneEventNumber % 32 ))) & 0x1) == 1 ) + return cOCT6100_ERR_TONE_DETECTION_TONE_ACTIVATED; + + + + /*=====================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteToneDetectEvent + +Description: Write the tone detection event in the channel main structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulChannelIndex Index of the channel within the API's channel list. +f_ulToneEventNumber Event number of the tone to be activated. +f_ulExtToneChanIndex Index of the extended tone detection channel. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteToneDetectEvent +UINT32 Oct6100ApiWriteToneDetectEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulToneEventNumber, + + IN UINT32 f_ulExtToneChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT16 usReadData; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*=======================================================================*/ + /* Read the current event config about to be modified. */ + + ReadParams.ulReadAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_ulChannelIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ); + ReadParams.ulReadAddress += cOCT6100_CH_MAIN_TONE_EVENT_OFFSET; + ReadParams.ulReadAddress += (f_ulToneEventNumber / 16) * 2; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + /* Set the tone event in the channel main memory for the requested direction. */ + + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + WriteParams.usWriteData = usReadData; + WriteParams.usWriteData |= ( 0x1 << ( 15 - ( f_ulToneEventNumber % 16 ))); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + /* Also program the extended channel if one is present. */ + + if ( f_ulExtToneChanIndex != cOCT6100_INVALID_INDEX ) + { + /* Read the current event config about to be modified. */ + ReadParams.ulReadAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_ulExtToneChanIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ); + ReadParams.ulReadAddress += cOCT6100_CH_MAIN_TONE_EVENT_OFFSET; + ReadParams.ulReadAddress += (f_ulToneEventNumber / 16) * 2; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write the tone event in the channel main memory for the requested direction. */ + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + WriteParams.usWriteData = usReadData; + WriteParams.usWriteData |= ( 0x1 << ( 15 - ( f_ulToneEventNumber % 16 ))); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateChanToneDetectEntry + +Description: Update the echo channel entry to store the info about the tone + being configured to generate detection events. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulChannelIndex Index of the channel within the API's channel list. +f_ulToneEventNumber Enabled tone event number. +f_ulExtToneChanIndex Index of the extended tone detection channel. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateChanToneDetectEntry +UINT32 Oct6100ApiUpdateChanToneDetectEntry ( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulToneEventNumber, + IN UINT32 f_ulExtToneChanIndex ) +{ + tPOCT6100_API_CHANNEL pEchoChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulToneEntry; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Update the channel entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_ulChannelIndex ); + + /* Set the corresponding bit in the channel array. */ + ulToneEntry = pEchoChanEntry->aulToneConf[ f_ulToneEventNumber / 32 ]; + + /* Modify the entry. */ + ulToneEntry |= ( 0x1 << ( 31 - ( f_ulToneEventNumber % 32 ))); + + /* Copy back the new value. */ + pEchoChanEntry->aulToneConf[ f_ulToneEventNumber / 32 ] = ulToneEntry; + + /* Configure also the extended channel if necessary. */ + if ( f_ulExtToneChanIndex != cOCT6100_INVALID_INDEX ) + { + /* Update the channel entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_ulExtToneChanIndex ); + + /* Set the corresponding bit in the channel array. */ + ulToneEntry = pEchoChanEntry->aulToneConf[ f_ulToneEventNumber / 32 ]; + + /* Modify the entry. */ + ulToneEntry |= ( 0x1 << ( 31 - ( f_ulToneEventNumber % 32 ))); + + /* Copy back the new value. */ + pEchoChanEntry->aulToneConf[ f_ulToneEventNumber / 32 ] = ulToneEntry; + } + + /* Check for the SS tone events that could have been generated before. */ + if ( f_ulExtToneChanIndex == cOCT6100_INVALID_INDEX ) + { + BOOL fSSTone; + UINT32 ulResult; + + ulResult = Oct6100ApiIsSSTone( f_pApiInstance, pSharedInfo->ImageInfo.aToneInfo[ f_ulToneEventNumber ].ulToneID, &fSSTone ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Is this a signaling system tone? */ + if ( fSSTone == TRUE ) + { + /* Check if must generate an event for the last detected SS tone. */ + if ( ( pEchoChanEntry->ulLastSSToneDetected != cOCT6100_INVALID_INDEX ) + && ( pEchoChanEntry->ulLastSSToneDetected == pSharedInfo->ImageInfo.aToneInfo[ f_ulToneEventNumber ].ulToneID ) ) + { + /* Must write an event for this. */ + tPOCT6100_API_TONE_EVENT pSoftEvent; + + /* If enough space. */ + if ( ( ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1 ) != pSharedInfo->SoftBufs.ulToneEventBufferReadPtr ) && + ( ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1 ) != pSharedInfo->SoftBufs.ulToneEventBufferSize || pSharedInfo->SoftBufs.ulToneEventBufferReadPtr != 0 ) ) + { + /* Form the event for this captured tone. */ + mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent ) + pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr; + + pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_ulChannelIndex; + pSoftEvent->ulUserChanId = pEchoChanEntry->ulUserChanId; + pSoftEvent->ulToneDetected = pSharedInfo->ImageInfo.aToneInfo[ f_ulToneEventNumber ].ulToneID; + pSoftEvent->ulTimestamp = pEchoChanEntry->ulLastSSToneTimestamp; + pSoftEvent->ulExtToneDetectionPort = cOCT6100_INVALID_VALUE; + pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT; + + /* Update the control variables of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr++; + if ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr == pSharedInfo->SoftBufs.ulToneEventBufferSize ) + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0; + + /* Set the interrupt manager such that the user knows that some tone events */ + /* are pending in the software Q. */ + pSharedInfo->IntrptManage.fToneEventsPending = TRUE; + } + else + { + /* Set the overflow flag of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++; + } + } + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ToneDetectionDisableSer + +Description: Disable the generation of events for a selected tone on the + specified channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pToneDetectDisable Pointer to tOCT6100_TONE_DETECTION_DISABLE structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ToneDetectionDisableSer +UINT32 Oct6100ToneDetectionDisableSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TONE_DETECTION_DISABLE f_pToneDetectDisable ) +{ + UINT32 ulChanIndex; + UINT32 ulExtToneChanIndex; + UINT32 ulToneEventNumber = 0; + UINT32 ulResult; + BOOL fDisableAll; + + + /* Check the user's configuration of the tone detection disable structure for errors. */ + ulResult = Oct6100ApiAssertToneDetectionParams( + f_pApiInstance, + f_pToneDetectDisable, + &ulChanIndex, + &ulToneEventNumber, + &ulExtToneChanIndex, + + &fDisableAll ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear the event to detect the specified tone. */ + ulResult = Oct6100ApiClearToneDetectionEvent( + f_pApiInstance, + ulChanIndex, + ulToneEventNumber, + ulExtToneChanIndex, + + fDisableAll ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the channel structure to indicate that the tone is no longer detected. */ + ulResult = Oct6100ApiReleaseToneDetectionEvent( + f_pApiInstance, + ulChanIndex, + ulToneEventNumber, + ulExtToneChanIndex, + fDisableAll ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertToneDetectionParams + +Description: Check the validity of the tone detection disable command. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pToneDetectDisable Pointer to tone detection disable structure. +f_pulChannelIndex Pointer to the channel index +f_pulToneEventNumber Pointer to the tone event number. +f_pulExtToneChanIndex Pointer to the extended channel index. +f_pfDisableAll Pointer to the flag specifying whether all tones + should be disabled. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertToneDetectionParams +UINT32 Oct6100ApiAssertToneDetectionParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TONE_DETECTION_DISABLE f_pToneDetectDisable, + OUT PUINT32 f_pulChannelIndex, + OUT PUINT32 f_pulToneEventNumber, + OUT PUINT32 f_pulExtToneChanIndex, + + OUT PBOOL f_pfDisableAll ) +{ + tPOCT6100_API_CHANNEL pEchoChannel; + UINT32 ulEntryOpenCnt; + UINT32 i; + + /*=====================================================================*/ + /* Check the echo channel handle. */ + + if ( (f_pToneDetectDisable->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_TONE_DETECTION_CHANNEL_HANDLE_INVALID; + + *f_pulChannelIndex = f_pToneDetectDisable->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK; + if ( *f_pulChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_TONE_DETECTION_CHANNEL_HANDLE_INVALID; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChannel, *f_pulChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pToneDetectDisable->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChannel->fReserved != TRUE ) + return cOCT6100_ERR_TONE_DETECTION_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChannel->byEntryOpenCnt ) + return cOCT6100_ERR_TONE_DETECTION_CHANNEL_HANDLE_INVALID; + + /* Return the extended channel index. */ + *f_pulExtToneChanIndex = pEchoChannel->usExtToneChanIndex; + + /* Check the disable all flag. */ + if ( f_pToneDetectDisable->fDisableAll != TRUE && f_pToneDetectDisable->fDisableAll != FALSE ) + return cOCT6100_ERR_TONE_DETECTION_DISABLE_ALL; + + /*=====================================================================*/ + /* Check the tone information. */ + + /* Find out if the tone is present in the build. */ + if ( f_pToneDetectDisable->fDisableAll == FALSE ) + { + for ( i = 0; i < cOCT6100_MAX_TONE_EVENT; i++ ) + { + if ( f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ i ].ulToneID == f_pToneDetectDisable->ulToneNumber ) + { + *f_pulToneEventNumber = i; + break; + } + } + + /* Check if tone is present. */ + if ( i == cOCT6100_MAX_TONE_EVENT ) + return cOCT6100_ERR_NOT_SUPPORTED_TONE_NOT_PRESENT_IN_FIRMWARE; + + + + /* Check if the requested tone is actually detected. */ + if ((( pEchoChannel->aulToneConf[ *f_pulToneEventNumber / 32 ] >> ( 31 - ( *f_pulToneEventNumber % 32 ))) & 0x1) == 0 ) + return cOCT6100_ERR_TONE_DETECTION_TONE_NOT_ACTIVATED; + } + + + /*=====================================================================*/ + + /* Return the disable all flag as requested. */ + *f_pfDisableAll = f_pToneDetectDisable->fDisableAll; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiClearToneDetectionEvent + +Description: Clear the buffer playout event in the channel main structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulChannelIndex Index of the channel within the API's channel list. +f_ulToneEventNumber Tone event number to be deactivated. +f_ulExtToneChanIndex Index of the extended tone detection channel. +f_fDisableAll Clear all activated tones. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiClearToneDetectionEvent +UINT32 Oct6100ApiClearToneDetectionEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulToneEventNumber, + IN UINT32 f_ulExtToneChanIndex, + + IN BOOL f_fDisableAll ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_WRITE_SMEAR_PARAMS SmearParams; + UINT32 ulResult; + UINT32 ulToneEventBaseAddress; + UINT16 usReadData; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + SmearParams.pProcessContext = f_pApiInstance->pProcessContext; + + SmearParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*=======================================================================*/ + /* Read the current event config about to be modified. */ + + ulToneEventBaseAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_ulChannelIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ); + ulToneEventBaseAddress += cOCT6100_CH_MAIN_TONE_EVENT_OFFSET; + + /* Check if must disable all tone events or not. */ + if ( f_fDisableAll == FALSE ) + { + ReadParams.ulReadAddress = ulToneEventBaseAddress; + ReadParams.ulReadAddress += (f_ulToneEventNumber / 16) * 2; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear the event in the channel main memory.*/ + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + WriteParams.usWriteData = usReadData; + WriteParams.usWriteData &= (~( 0x1 << ( 15 - ( f_ulToneEventNumber % 16 )))); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else /* if ( f_fDisableAll == TRUE ) */ + { + /* Clear all events in the channel main memory. */ + SmearParams.ulWriteLength = 4; + SmearParams.usWriteData = 0x0000; + SmearParams.ulWriteAddress = ulToneEventBaseAddress; + mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*=======================================================================*/ + /* Also program the extended channel if one is present. */ + + if ( f_ulExtToneChanIndex != cOCT6100_INVALID_INDEX ) + { + ulToneEventBaseAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_ulExtToneChanIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ); + ulToneEventBaseAddress += cOCT6100_CH_MAIN_TONE_EVENT_OFFSET; + + /* Check if must disable all tone events or not. */ + if ( f_fDisableAll == FALSE ) + { + /* Read the current event config about to be modified. */ + ReadParams.ulReadAddress = ulToneEventBaseAddress; + ReadParams.ulReadAddress += (f_ulToneEventNumber / 16) * 2; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear the event in the channel main memory.*/ + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + WriteParams.usWriteData = usReadData; + WriteParams.usWriteData &= (~( 0x1 << ( 15 - ( f_ulToneEventNumber % 16 )))); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else /* if ( f_fDisableAll == TRUE ) */ + { + /* Clear all events in the channel main memory.*/ + SmearParams.ulWriteLength = 4; + SmearParams.usWriteData = 0x0000; + SmearParams.ulWriteAddress = ulToneEventBaseAddress; + mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseToneDetectionEvent + +Description: Clear the entry made for this tone in the channel tone + enable array. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulChannelIndex Index of the channel within the API's channel list. +f_ulToneEventNumber Tone event number to be deactivated. +f_ulExtToneChanIndex Index of the extended tone detection channel. +f_fDisableAll Release all activated tones. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseToneDetectionEvent +UINT32 Oct6100ApiReleaseToneDetectionEvent ( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulToneEventNumber, + IN UINT32 f_ulExtToneChanIndex, + IN BOOL f_fDisableAll ) +{ + tPOCT6100_API_CHANNEL pEchoChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulToneEntry; + UINT32 ulResult; + UINT32 ulToneEventNumber; + BOOL fSSTone; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Update the channel entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_ulChannelIndex ); + + /* Check if must release all tone events. */ + if ( f_fDisableAll == FALSE ) + { + /* Set the corresponding bit in the channel array. */ + ulToneEntry = pEchoChanEntry->aulToneConf[ f_ulToneEventNumber / 32 ]; + + /* Modify the entry. */ + ulToneEntry &= (~( 0x1 << ( 31 - ( f_ulToneEventNumber % 32 )))); + + /* Copy back the new value. */ + pEchoChanEntry->aulToneConf[ f_ulToneEventNumber / 32 ] = ulToneEntry; + } + else /* if ( f_fDisableAll == TRUE ) */ + { + /* Clear all events. */ + Oct6100UserMemSet( pEchoChanEntry->aulToneConf, 0x00, sizeof( pEchoChanEntry->aulToneConf ) ); + } + + /* Configure also the extended channel if necessary. */ + if ( f_ulExtToneChanIndex != cOCT6100_INVALID_INDEX ) + { + /* Update the channel entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_ulExtToneChanIndex ); + + /* Check if must release all tone events. */ + if ( f_fDisableAll == FALSE ) + { + /* Set the corresponding bit in the channel array. */ + ulToneEntry = pEchoChanEntry->aulToneConf[ f_ulToneEventNumber / 32 ]; + + /* Modify the entry. */ + ulToneEntry &= (~( 0x1 << ( 31 - ( f_ulToneEventNumber % 32 )))); + + /* Copy back the new value. */ + pEchoChanEntry->aulToneConf[ f_ulToneEventNumber / 32 ] = ulToneEntry; + } + else /* if ( f_fDisableAll == TRUE ) */ + { + /* Clear all events. */ + Oct6100UserMemSet( pEchoChanEntry->aulToneConf, 0x00, sizeof( pEchoChanEntry->aulToneConf ) ); + } + } + + /* Re-enable the SS7 tones */ + for ( ulToneEventNumber = 0; ulToneEventNumber < cOCT6100_MAX_TONE_EVENT; ulToneEventNumber++ ) + { + /* Check if the current tone is a SS tone. */ + ulResult = Oct6100ApiIsSSTone( + f_pApiInstance, + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulToneID, + &fSSTone ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( fSSTone == TRUE ) + { + /* Write to all resources needed to activate tone detection on this SS tone. */ + ulResult = Oct6100ApiWriteToneDetectEvent( + f_pApiInstance, + f_ulChannelIndex, + ulToneEventNumber, + + cOCT6100_INVALID_INDEX ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiIsSSTone + +Description: Check if specified tone number is a special signaling + system tone. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulToneEventNumber Tone event number to be checked against. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiIsSSTone +UINT32 Oct6100ApiIsSSTone( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulToneEventNumber, + OUT PBOOL f_fSSTone ) +{ + *f_fSSTone = FALSE; + + switch( f_ulToneEventNumber ) + { + case cOCT6100_TONE_SIN_SYSTEM7_2000 : + case cOCT6100_TONE_SIN_SYSTEM7_1780 : + case cOCT6100_TONE_ROUT_G168_2100GB_ON : + case cOCT6100_TONE_ROUT_G168_2100GB_WSPR : + case cOCT6100_TONE_ROUT_G168_1100GB_ON : + case cOCT6100_TONE_ROUT_G168_2100GB_ON_WIDE_A : + case cOCT6100_TONE_ROUT_G168_2100GB_ON_WIDE_B : + case cOCT6100_TONE_ROUT_G168_2100GB_WSPR_WIDE : + case cOCT6100_TONE_SOUT_G168_2100GB_ON : + case cOCT6100_TONE_SOUT_G168_2100GB_WSPR : + case cOCT6100_TONE_SOUT_G168_1100GB_ON : + case cOCT6100_TONE_SOUT_G168_2100GB_ON_WIDE_A : + case cOCT6100_TONE_SOUT_G168_2100GB_ON_WIDE_B : + case cOCT6100_TONE_SOUT_G168_2100GB_WSPR_WIDE : + case cOCT6100_TONE_SIN_SYSTEM5_2400 : + case cOCT6100_TONE_SIN_SYSTEM5_2600 : + case cOCT6100_TONE_SIN_SYSTEM5_2400_2600 : + *f_fSSTone = TRUE; + break; + default: + break; + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiIsSSTone + +Description: Check if specified tone number is a 2100 special signaling + system tone. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulToneEventNumber Tone event number to be checked against. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiIs2100Tone +UINT32 Oct6100ApiIs2100Tone( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulToneEventNumber, + OUT PBOOL f_fIs2100Tone ) +{ + *f_fIs2100Tone = FALSE; + + switch( f_ulToneEventNumber ) + { + case cOCT6100_TONE_ROUT_G168_2100GB_ON : + case cOCT6100_TONE_ROUT_G168_2100GB_WSPR : + case cOCT6100_TONE_ROUT_G168_2100GB_ON_WIDE_A : + case cOCT6100_TONE_ROUT_G168_2100GB_ON_WIDE_B : + case cOCT6100_TONE_ROUT_G168_2100GB_WSPR_WIDE : + case cOCT6100_TONE_SOUT_G168_2100GB_ON : + case cOCT6100_TONE_SOUT_G168_2100GB_WSPR : + case cOCT6100_TONE_SOUT_G168_2100GB_ON_WIDE_A : + case cOCT6100_TONE_SOUT_G168_2100GB_ON_WIDE_B : + case cOCT6100_TONE_SOUT_G168_2100GB_WSPR_WIDE : + *f_fIs2100Tone = TRUE; + break; + default: + break; + } + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tsi_cnct.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tsi_cnct.c new file mode 100644 index 0000000..e885aa4 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tsi_cnct.c @@ -0,0 +1,1023 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tsi_cnct.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains functions used to open and close TSI connections + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 38 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_tsi_cnct_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_tsi_cnct_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_tsst_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_tsi_cnct_priv.h" + +/**************************** PUBLIC FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100TsiCnctOpen + +Description: This function opens a TSI connection between two TDM timeslots. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pTsiCnctOpen Pointer to TSI connection open structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100TsiCnctOpenDef +UINT32 Oct6100TsiCnctOpenDef( + tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen ) +{ + f_pTsiCnctOpen->pulTsiCnctHndl = NULL; + + f_pTsiCnctOpen->ulInputTimeslot = cOCT6100_INVALID_TIMESLOT; + f_pTsiCnctOpen->ulInputStream = cOCT6100_INVALID_STREAM; + f_pTsiCnctOpen->ulOutputTimeslot = cOCT6100_INVALID_TIMESLOT; + f_pTsiCnctOpen->ulOutputStream = cOCT6100_INVALID_STREAM; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100TsiCnctOpen +UINT32 Oct6100TsiCnctOpen( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100TsiCnctOpenSer( f_pApiInstance, f_pTsiCnctOpen ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100TsiCnctClose + +Description: This function closes a TSI connection. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pTsiCnctClose Pointer to TSI connection close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100TsiCnctCloseDef +UINT32 Oct6100TsiCnctCloseDef( + tPOCT6100_TSI_CNCT_CLOSE f_pTsiCnctClose ) +{ + f_pTsiCnctClose->ulTsiCnctHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100TsiCnctClose +UINT32 Oct6100TsiCnctClose( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_TSI_CNCT_CLOSE f_pTsiCnctClose ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100TsiCnctCloseSer( f_pApiInstance, f_pTsiCnctClose ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetTsiCnctSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management the TSI memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pOpenChip Pointer to chip configuration struct. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetTsiCnctSwSizes +UINT32 Oct6100ApiGetTsiCnctSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + + /* Determine the amount of memory required for the API TSI connection list. */ + f_pInstSizes->ulTsiCnctList = f_pOpenChip->ulMaxTsiCncts * sizeof( tOCT6100_API_TSI_CNCT ); + + if ( f_pOpenChip->ulMaxTsiCncts > 0 ) + { + /* Calculate memory needed for TSI memory allocation. */ + ulResult = OctapiLlmAllocGetSize( f_pOpenChip->ulMaxTsiCncts, &f_pInstSizes->ulTsiCnctAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_48; + } + else + { + f_pInstSizes->ulTsiCnctAlloc = 0; + } + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulTsiCnctList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulTsiCnctAlloc, ulTempVar ) + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiTsiCnctSwInit + +Description: Initializes all elements of the instance structure associated + to the TSI memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiTsiCnctSwInit +UINT32 Oct6100ApiTsiCnctSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_API_TSI_CNCT pChannelsTsiList; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulMaxTsiChannels; + PVOID pTsiChannelsAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Initialize the TSI connections API list. */ + ulMaxTsiChannels = pSharedInfo->ChipConfig.usMaxTsiCncts; + + mOCT6100_GET_TSI_CNCT_LIST_PNT( pSharedInfo, pChannelsTsiList ) + + /* Clear the memory. */ + Oct6100UserMemSet( pChannelsTsiList, 0x00, sizeof(tOCT6100_API_TSI_CNCT) * ulMaxTsiChannels ); + + /* Set all entries in the TSI connections list to unused. */ + if ( ulMaxTsiChannels > 0 ) + { + mOCT6100_GET_TSI_CNCT_ALLOC_PNT( pSharedInfo, pTsiChannelsAlloc ) + + ulResult = OctapiLlmAllocInit( &pTsiChannelsAlloc, ulMaxTsiChannels ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_49; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100TsiCnctOpenSer + +Description: Opens a TSI connection. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pTsiCnctOpen Pointer to a tOCT6100_TSI_CNCT_OPEN structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100TsiCnctOpenSer +UINT32 Oct6100TsiCnctOpenSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen ) +{ + UINT16 usTsiChanIndex; + UINT16 usTsiMemIndex; + UINT16 usInputTsstIndex; + UINT16 usOutputTsstIndex; + UINT32 ulResult; + + /* Check the user's configuration of the TSI connection open structure for errors. */ + ulResult = Oct6100ApiCheckTsiParams( f_pApiInstance, f_pTsiCnctOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the TSI connection. */ + ulResult = Oct6100ApiReserveTsiResources( f_pApiInstance, f_pTsiCnctOpen, &usTsiChanIndex, &usTsiMemIndex, &usInputTsstIndex, &usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write all necessary structures to activate the TSI connection. */ + ulResult = Oct6100ApiWriteTsiStructs( f_pApiInstance, f_pTsiCnctOpen, usTsiMemIndex, usInputTsstIndex, usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the TSI connection entry in the API list. */ + ulResult = Oct6100ApiUpdateTsiEntry( f_pApiInstance, f_pTsiCnctOpen, usTsiChanIndex, usTsiMemIndex, usInputTsstIndex, usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckTsiParams + +Description: Checks the user's TSI connection open configuration for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pTsiCnctOpen Pointer to TSI connection open configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckTsiParams +UINT32 Oct6100ApiCheckTsiParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen ) +{ + UINT32 ulResult; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxTsiCncts == 0 ) + return cOCT6100_ERR_TSI_CNCT_DISABLED; + + if ( f_pTsiCnctOpen->pulTsiCnctHndl == NULL ) + return cOCT6100_ERR_TSI_CNCT_INVALID_HANDLE; + + /* Check the input TDM streams, timeslots component for errors. */ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + cOCT6100_NUMBER_TSSTS_1, + f_pTsiCnctOpen->ulInputTimeslot, + f_pTsiCnctOpen->ulInputStream, + cOCT6100_INPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_TSI_CNCT_INPUT_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_TSI_CNCT_INPUT_STREAM; + } + else + { + return ulResult; + } + } + + /* Check the output TDM streams, timeslots component for errors. */ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + cOCT6100_NUMBER_TSSTS_1, + f_pTsiCnctOpen->ulOutputTimeslot, + f_pTsiCnctOpen->ulOutputStream, + cOCT6100_OUTPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_TSI_CNCT_OUTPUT_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_TSI_CNCT_OUTPUT_STREAM; + } + else + { + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveTsiResources + +Description: Reserves all resources needed for the new TSI connection. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pTsiCnctOpen Pointer to tsi channel configuration structure. +f_pusTsiChanIndex Allocated entry in TSI channel list. +f_pusTsiMemIndex Allocated entry in the TSI control memory. +f_pusInputTsstIndex TSST memory index of the input samples. +f_pusOutputTsstIndex TSST memory index of the output samples. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveTsiResources +UINT32 Oct6100ApiReserveTsiResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen, + OUT PUINT16 f_pusTsiChanIndex, + OUT PUINT16 f_pusTsiMemIndex, + OUT PUINT16 f_pusInputTsstIndex, + OUT PUINT16 f_pusOutputTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + UINT32 ulTempVar; + BOOL fTsiChanEntry = FALSE; + BOOL fTsiMemEntry = FALSE; + BOOL fInputTsst = FALSE; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Reserve an entry in the TSI connection list. */ + ulResult = Oct6100ApiReserveTsiCnctEntry( f_pApiInstance, f_pusTsiChanIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fTsiChanEntry = TRUE; + + /* Find a TSI memory entry. */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, f_pusTsiMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fTsiMemEntry = TRUE; + + /* Reserve the input TSST entry. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + f_pTsiCnctOpen->ulInputTimeslot, + f_pTsiCnctOpen->ulInputStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_INPUT_TSST, + f_pusInputTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fInputTsst = TRUE; + + /* Reserve the output TSST entry. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + f_pTsiCnctOpen->ulOutputTimeslot, + f_pTsiCnctOpen->ulOutputStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_OUTPUT_TSST, + f_pusOutputTsstIndex, + NULL ); + } + } + else + { + /* Return an error other then a fatal. */ + ulResult = cOCT6100_ERR_TSI_CNCT_NO_MORE_TSI_AVAILABLE; + } + } + + if ( ulResult != cOCT6100_ERR_OK ) + { + if( fTsiChanEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiCnctEntry( f_pApiInstance, *f_pusTsiChanIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fTsiMemEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, *f_pusTsiMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fInputTsst == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + f_pTsiCnctOpen->ulInputTimeslot, + f_pTsiCnctOpen->ulInputStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteTsiStructs + +Description: Performs all the required structure writes to configure the + new TSI connection. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pTsiCnctOpen Pointer to tsi connection open structure. +f_usTsiMemIndex Allocated entry in the TSI control memory. +f_usInputTsstIndex TSST memory index of the input samples. +f_usOutputTsstIndex TSST memory index of the output samples. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteTsiStructs +UINT32 Oct6100ApiWriteTsiStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen, + IN UINT16 f_usTsiMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*==================================================================================*/ + /* Configure the TSST control memory.*/ + + /* Set the input TSST control entry.*/ + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_usInputTsstIndex, + f_usTsiMemIndex, + cOCT6100_PCM_U_LAW ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the output TSST control entry. */ + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_usOutputTsstIndex, + cOCT6100_ADPCM_IN_LOW_BITS, + 1, + f_usTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==================================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateTsiEntry + +Description: Updates the new TSI connection in the TSI connection list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pTsiCnctOpen Pointer to TSI connection open configuration structure. +f_usTsiMemIndex Allocated entry in TSI chariot memory. +f_usTsiChanIndex Allocated entry in the TSI channel list. +f_usInputTsstIndex TSST control memory index of the input TSST. +f_usOutputTsstIndex TSST control memory index of the output TSST. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateTsiEntry +UINT32 Oct6100ApiUpdateTsiEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen, + IN UINT16 f_usTsiChanIndex, + IN UINT16 f_usTsiMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ) +{ + tPOCT6100_API_TSI_CNCT pTsiCnctEntry; + + /*================================================================================*/ + /* Obtain a pointer to the new TSI connection's list entry. */ + + mOCT6100_GET_TSI_CNCT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsiCnctEntry, f_usTsiChanIndex ) + + /* Copy the TSI's configuration and allocated resources. */ + pTsiCnctEntry->usInputTimeslot = (UINT16)( f_pTsiCnctOpen->ulInputTimeslot & 0xFFFF ); + pTsiCnctEntry->usInputStream = (UINT16)( f_pTsiCnctOpen->ulInputStream & 0xFFFF ); + + pTsiCnctEntry->usOutputTimeslot = (UINT16)( f_pTsiCnctOpen->ulOutputTimeslot & 0xFFFF ); + pTsiCnctEntry->usOutputStream = (UINT16)( f_pTsiCnctOpen->ulOutputStream & 0xFFFF ); + + /* Store hardware related information. */ + pTsiCnctEntry->usTsiMemIndex = f_usTsiMemIndex; + pTsiCnctEntry->usInputTsstIndex = f_usInputTsstIndex; + pTsiCnctEntry->usOutputTsstIndex = f_usOutputTsstIndex; + + /* Form handle returned to user. */ + *f_pTsiCnctOpen->pulTsiCnctHndl = cOCT6100_HNDL_TAG_TSI_CNCT | (pTsiCnctEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_usTsiChanIndex; + + /* Finally, mark the connection as opened. */ + pTsiCnctEntry->fReserved = TRUE; + + /* Increment the number of TSI connection opened. */ + f_pApiInstance->pSharedInfo->ChipStats.usNumberTsiCncts++; + + /*================================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100TsiCnctCloseSer + +Description: Closes a TSI connection. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pTsiCnctClose Pointer to TSI connection close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100TsiCnctCloseSer +UINT32 Oct6100TsiCnctCloseSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TSI_CNCT_CLOSE f_pTsiCnctClose ) +{ + UINT16 usTsiChanIndex; + UINT16 usTsiMemIndex; + UINT16 usInputTsstIndex; + UINT16 usOutputTsstIndex; + UINT32 ulResult; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertTsiParams( f_pApiInstance, f_pTsiCnctClose, &usTsiChanIndex, &usTsiMemIndex, &usInputTsstIndex, &usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the TSI channel. */ + ulResult = Oct6100ApiInvalidateTsiStructs( f_pApiInstance, usInputTsstIndex, usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the TSI connection. */ + ulResult = Oct6100ApiReleaseTsiResources( f_pApiInstance, usTsiChanIndex, usTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Invalidate the handle. */ + f_pTsiCnctClose->ulTsiCnctHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertTsiParams + +Description: Validate the handle given by the user and verify the state of + the TSI connection about to be closed. + Also returns all required information to deactivate the connection. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pTsiCnctClose Pointer to TSI connection close structure. +f_pusTsiChanIndex Index of the TSI connection structure in the API list. +f_pusTsiMemIndex Index of the TSI entry within the TSI chariot memory +f_pusInputTsstIndex Index of the input entry in the TSST control memory. +f_pusOutputTsstIndex Index of the output entry in the TSST control memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertTsiParams +UINT32 Oct6100ApiAssertTsiParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TSI_CNCT_CLOSE f_pTsiCnctClose, + OUT PUINT16 f_pusTsiChanIndex, + OUT PUINT16 f_pusTsiMemIndex, + OUT PUINT16 f_pusInputTsstIndex, + OUT PUINT16 f_pusOutputTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_TSI_CNCT pTsiEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pTsiCnctClose->ulTsiCnctHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_TSI_CNCT ) + return cOCT6100_ERR_TSI_CNCT_INVALID_HANDLE; + + *f_pusTsiChanIndex = (UINT16)( f_pTsiCnctClose->ulTsiCnctHndl & cOCT6100_HNDL_INDEX_MASK ); + + if ( *f_pusTsiChanIndex >= pSharedInfo->ChipConfig.usMaxTsiCncts ) + return cOCT6100_ERR_TSI_CNCT_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_TSI_CNCT_ENTRY_PNT( pSharedInfo, pTsiEntry, *f_pusTsiChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pTsiCnctClose->ulTsiCnctHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pTsiEntry->fReserved != TRUE ) + return cOCT6100_ERR_TSI_CNCT_NOT_OPEN; + if ( ulEntryOpenCnt != pTsiEntry->byEntryOpenCnt ) + return cOCT6100_ERR_TSI_CNCT_INVALID_HANDLE; + + /* Return info needed to close the channel and release all resources. */ + *f_pusInputTsstIndex = pTsiEntry->usInputTsstIndex; + *f_pusOutputTsstIndex = pTsiEntry->usOutputTsstIndex; + *f_pusTsiMemIndex = pTsiEntry->usTsiMemIndex; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInvalidateTsiStructs + +Description: This function closes a TSI connection. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usInputTsstIndex Index of the input entry in the TSST control memory. +f_usOutputTsstIndex Index of the output entry in the TSST control memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInvalidateTsiStructs +UINT32 Oct6100ApiInvalidateTsiStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*==================================================================================*/ + /* Deactivate the TSST control memory. */ + + /* Set the input TSST control entry to unused. */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( f_usInputTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = 0x0000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the output TSST control entry to unused. */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( f_usOutputTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = 0x0000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==================================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseTsiResources + +Description: Release and clear the API entry associated to the TSI channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usTsiChanIndex Index of the TSI connection in the API list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseTsiResources +UINT32 Oct6100ApiReleaseTsiResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsiChanIndex, + IN UINT16 f_usTsiMemIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_TSI_CNCT pTsiEntry; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_TSI_CNCT_ENTRY_PNT( pSharedInfo, pTsiEntry, f_usTsiChanIndex ); + + /* Release the entry in the TSI connection list. */ + ulResult = Oct6100ApiReleaseTsiCnctEntry( f_pApiInstance, f_usTsiChanIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, f_usTsiMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Release the input entry. */ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pTsiEntry->usInputTimeslot, + pTsiEntry->usInputStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Release the output TSST entry. */ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pTsiEntry->usOutputTimeslot, + pTsiEntry->usOutputStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + } + } + } + + /* Check if an error occured while releasing the reserved resources. */ + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult >= cOCT6100_ERR_FATAL ) + return ulResult; + else + return cOCT6100_ERR_FATAL_4A; + } + + /*=============================================================*/ + /* Update the TSI connection's list entry. */ + + /* Mark the connection as closed. */ + pTsiEntry->fReserved = FALSE; + pTsiEntry->byEntryOpenCnt++; + + /* Decrement the number of TSI connection opened. */ + f_pApiInstance->pSharedInfo->ChipStats.usNumberTsiCncts--; + + /*=============================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveTsiCnctEntry + +Description: Reserves one of the TSI connection API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pusTsiChanIndex Resulting index reserved in the TSI channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveTsiCnctEntry +UINT32 Oct6100ApiReserveTsiCnctEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusTsiChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pTsiChanAlloc; + UINT32 ulResult; + UINT32 ulTsiIndex; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_TSI_CNCT_ALLOC_PNT( pSharedInfo, pTsiChanAlloc ) + + ulResult = OctapiLlmAllocAlloc( pTsiChanAlloc, &ulTsiIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_TSI_CNCT_ALL_CHANNELS_ARE_OPENED; + else + return cOCT6100_ERR_FATAL_4B; + } + + *f_pusTsiChanIndex = (UINT16)( ulTsiIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseTsiCnctEntry + +Description: Releases the specified TSI connection API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usTsiChanIndex Index reserved in the TSI channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseTsiCnctEntry +UINT32 Oct6100ApiReleaseTsiCnctEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsiChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pTsiChanAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_TSI_CNCT_ALLOC_PNT( pSharedInfo, pTsiChanAlloc ) + + ulResult = OctapiLlmAllocDealloc( pTsiChanAlloc, f_usTsiChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_4C; + } + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tsst.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tsst.c new file mode 100644 index 0000000..d3235a1 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tsst.c @@ -0,0 +1,572 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tsst.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the functions used to manage the allocation of TSST + control structures in internal memory. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 39 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_tsst_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_tsst_priv.h" + + +/**************************** PRIVATE FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetTsstSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of TSSTs. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetTsstSwSizes +UINT32 Oct6100ApiGetTsstSwSizes( + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + + /* Determine amount of TSST needed for TSST allocation table. */ + f_pInstSizes->ulTsstAlloc = 4096 / 8; + + /* Calculate the API memory required for the TSST entry list. */ + f_pInstSizes->ulTsstEntryList = cOCT6100_MAX_TSSTS * sizeof( tOCT6100_API_TSST_ENTRY ); + + /* Calculate memory needed for TSST entry allocation. */ + ulResult = OctapiLlmAllocGetSize( cOCT6100_MAX_TSSTS, &f_pInstSizes->ulTsstEntryAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_4D; + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulTsstAlloc, ulTempVar ); + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulTsstEntryList, ulTempVar ); + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulTsstEntryAlloc, ulTempVar ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiTsstSwInit + +Description: Initializes all elements of the instance structure associated + to the TSST control entries. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This tsst is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiTsstSwInit +UINT32 Oct6100ApiTsstSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_TSST_ENTRY pTsstList; + PUINT32 pulTsstAlloc; + PVOID pTsstListAlloc; + UINT32 ulResult; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Initialize the TSST allocation table to "all free". */ + mOCT6100_GET_TSST_ALLOC_PNT( pSharedInfo, pulTsstAlloc ); + Oct6100UserMemSet( pulTsstAlloc, 0x00, 512 ); + + /* Initialize all the TSST list entries. */ + mOCT6100_GET_TSST_LIST_PNT( pSharedInfo, pTsstList ); + Oct6100UserMemSet( pTsstList, 0xFF, cOCT6100_MAX_TSSTS * sizeof(tOCT6100_API_TSST_ENTRY) ); + + /* Initialize the allocation list to manage the TSST entries.*/ + mOCT6100_GET_TSST_LIST_ALLOC_PNT( pSharedInfo, pTsstListAlloc ) + + ulResult = OctapiLlmAllocInit( &pTsstListAlloc, cOCT6100_MAX_TSSTS ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_4E; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiValidateTsst + +Description: Validates a timeslot, stream combination. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This tsst is used to keep + the present state of the chip and all its resources. + +f_ulTimeslot Timeslot component of the TDM TSST. +f_ulStream Stream component of the TDM TSST. +f_ulNumTssts Number of TSST required. +f_ulDirection Direction of the TSST (Input or Output). + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiValidateTsst +UINT32 Oct6100ApiValidateTsst( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulNumTssts, + IN UINT32 f_ulTimeslot, + IN UINT32 f_ulStream, + IN UINT32 f_ulDirection ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain local pointer to chip configuration. */ + pChipConfig = &pSharedInfo->ChipConfig; + + /* Check the TDM streams, timeslots component for errors. */ + if ( f_ulTimeslot == cOCT6100_UNASSIGNED && + f_ulStream != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_TSST_TIMESLOT; + + if ( f_ulTimeslot != cOCT6100_UNASSIGNED && + f_ulStream == cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_TSST_STREAM; + + if ( f_ulStream >= pChipConfig->byMaxTdmStreams ) + return cOCT6100_ERR_TSST_STREAM; + + /* Check timeslot value based on the frequenccy of the selected stream. */ + switch ( pChipConfig->aulTdmStreamFreqs[ f_ulStream / 4 ] ) + { + case cOCT6100_TDM_STREAM_FREQ_2MHZ: + if ( f_ulTimeslot >= 32 ) + return cOCT6100_ERR_TSST_TIMESLOT; + break; + case cOCT6100_TDM_STREAM_FREQ_4MHZ: + if ( f_ulTimeslot >= 64 ) + return cOCT6100_ERR_TSST_TIMESLOT; + break; + case cOCT6100_TDM_STREAM_FREQ_8MHZ: + if ( f_ulTimeslot >= 128 ) + return cOCT6100_ERR_TSST_TIMESLOT; + break; + case cOCT6100_TDM_STREAM_FREQ_16MHZ: + if ( f_ulTimeslot >= 256 ) + return cOCT6100_ERR_TSST_TIMESLOT; + + /* Check the stream value based on the direction. */ + if ( f_ulDirection == cOCT6100_INPUT_TSST && f_ulStream >= 16 ) + { + return cOCT6100_ERR_TSST_STREAM; + } + else if( f_ulDirection == cOCT6100_OUTPUT_TSST && f_ulStream < 16 ) + { + return cOCT6100_ERR_TSST_STREAM; + } + + break; + default: + return cOCT6100_ERR_FATAL_DC; + } + + /* Stream must be odd if two TSSTs are required. */ + if ( f_ulNumTssts == 2 && ( ( f_ulStream & 0x1) != 0x1 ) ) + return cOCT6100_ERR_TSST_STREAM; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveTsst + +Description: Reserves a TSST, only one TSI entry can access a TSST at any one + time. + If the pointer f_pulTsstListIndex is set to NULL, no TSST list + entry will be reserved. + + The index in TSST control memory returned is based on the frequency + of the streams where the TSST is located and on the direction of + the TSST ( input or output ). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This tsst is used to keep + the present state of the chip and all its resources. + +f_ulTimeslot Timeslot component of the TDM TSST. +f_ulNumTssts Number of TSSTs required. +f_ulStream Stream component of the TDM TSST. +f_ulDirection Whether the TSST in and input TSST or output TSST. +f_pusTsstMemIndex Index of the resulting TSST in the TSST control memory. +f_pusTsstListIndex Index in the TSST list of the current entry. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveTsst +UINT32 Oct6100ApiReserveTsst( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulTimeslot, + IN UINT32 f_ulStream, + IN UINT32 f_ulNumTsst, + IN UINT32 f_ulDirection, + OUT PUINT16 f_pusTsstMemIndex, + OUT PUINT16 f_pusTsstListIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pTsstListAlloc; + PUINT32 pulTsstAlloc; + UINT32 ulResult = cOCT6100_ERR_OK; + UINT32 ulStream; + UINT32 ulTimeslot; + + /* Get local pointer to shared portion of API instance structure. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_TSST_ALLOC_PNT( f_pApiInstance->pSharedInfo, pulTsstAlloc ); + + /*==================================================================================*/ + /* Now make the proper conversion to obtain the TSST value. */ + + /* Save the timeslot and stream value received. */ + ulStream = f_ulStream; + ulTimeslot = f_ulTimeslot; + + /* Set the TSST index associated to this stream, timeslot combination. */ + switch ( f_pApiInstance->pSharedInfo->ChipConfig.aulTdmStreamFreqs[ f_ulStream / 4 ] ) + { + case cOCT6100_TDM_STREAM_FREQ_16MHZ: + if ( f_ulDirection == cOCT6100_INPUT_TSST ) + { + ulStream = f_ulStream + ( f_ulTimeslot % 2 ) * 16; + ulTimeslot = f_ulTimeslot / 2; + } + else /* f_ulDirection == cOCT6100_OUTPUT_TSST */ + { + ulStream = ( f_ulStream - 16 ) + ( f_ulTimeslot % 2 ) * 16; + + if ( f_ulStream < 28 && ((f_ulTimeslot % 2) == 1) ) + { + ulTimeslot = ((f_ulTimeslot / 2) + 4) % 128; + } + else + { + ulTimeslot = f_ulTimeslot / 2 ; + } + } + + *f_pusTsstMemIndex = (UINT16)( ulTimeslot * 32 + ulStream ); + break; + + case cOCT6100_TDM_STREAM_FREQ_8MHZ: + *f_pusTsstMemIndex = (UINT16)( ulTimeslot * 32 + ulStream ); + break; + + case cOCT6100_TDM_STREAM_FREQ_4MHZ: + *f_pusTsstMemIndex = (UINT16)( ulTimeslot * 32 * 2 ); + if ( f_ulDirection == cOCT6100_OUTPUT_TSST ) + { + *f_pusTsstMemIndex = (UINT16)( *f_pusTsstMemIndex + ulStream ); + } + else /* if ( f_ulDirection == cOCT6100_INPUT_TSST ) */ + { + *f_pusTsstMemIndex = (UINT16)( ( 1 * 32 + ulStream ) + *f_pusTsstMemIndex ); + } + break; + + case cOCT6100_TDM_STREAM_FREQ_2MHZ: + *f_pusTsstMemIndex = (UINT16)( ulTimeslot * 32 * 4 ); + if ( f_ulDirection == cOCT6100_OUTPUT_TSST ) + { + *f_pusTsstMemIndex = (UINT16)( ulStream + *f_pusTsstMemIndex ); + } + else /* if ( f_ulDirection == cOCT6100_INPUT_TSST ) */ + { + *f_pusTsstMemIndex = (UINT16)( ( 3 * 32 + ulStream ) + *f_pusTsstMemIndex ); + } + break; + + default: + ulResult = cOCT6100_ERR_FATAL_8B; + } + /*======================================================================*/ + + + /*======================================================================*/ + /* First reserve the TSST. */ + + /* Get local pointer to TSST's entry in allocation table. */ + switch ( pSharedInfo->ChipConfig.aulTdmStreamFreqs[ ulStream / 4 ] ) + { + case cOCT6100_TDM_STREAM_FREQ_2MHZ: + ulTimeslot *= 4; + break; + case cOCT6100_TDM_STREAM_FREQ_4MHZ: + ulTimeslot *= 2; + break; + case cOCT6100_TDM_STREAM_FREQ_8MHZ: + ulTimeslot *= 1; + break; + case cOCT6100_TDM_STREAM_FREQ_16MHZ: + ulTimeslot *= 1; + break; + default: + return cOCT6100_ERR_FATAL_DD; + } + + /* Check if entry is already reserved. */ + if ( ((pulTsstAlloc[ ulTimeslot ] >> ulStream) & 0x1) == 0x1 ) + return cOCT6100_ERR_TSST_TSST_RESERVED; + + /* Check and reserve the associated TSST if required. */ + if ( f_ulNumTsst == 2 ) + { + /* Check if entry is already reserved. */ + if ( ((pulTsstAlloc[ ulTimeslot ] >> (ulStream - 1) ) & 0x1) == 0x1 ) + return cOCT6100_ERR_TSST_ASSOCIATED_TSST_RESERVED; + + /* The entry is free, it won't anymore. */ + pulTsstAlloc[ ulTimeslot ] |= (0x1 << (ulStream - 1)); + } + + /* The entry is free, it won't anymore.*/ + pulTsstAlloc[ ulTimeslot ] |= (0x1 << ulStream); + + /*======================================================================*/ + + + /*======================================================================*/ + /* Now reserve a TSST entry if requested. */ + + if ( f_pusTsstListIndex != NULL && ulResult == cOCT6100_ERR_OK ) + { + UINT32 ulTsstListIndex; + + /* Reserve a TSST entry in the API TSST list. */ + mOCT6100_GET_TSST_LIST_ALLOC_PNT( f_pApiInstance->pSharedInfo, pTsstListAlloc ); + + ulResult = OctapiLlmAllocAlloc( pTsstListAlloc, &ulTsstListIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + ulResult = cOCT6100_ERR_TSST_ALL_TSSTS_ARE_OPENED; + else + ulResult = cOCT6100_ERR_FATAL_52; + } + + *f_pusTsstListIndex = (UINT16)( ulTsstListIndex & 0xFFFF ); + } + /*======================================================================*/ + + + /*======================================================================*/ + /* Check the result of the TSST list reservation. */ + + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Release the previously reserved TSST. */ + if ( f_ulNumTsst == 2 ) + { + /* Clear the entry. */ + pulTsstAlloc[ ulTimeslot ] &= ~(0x1 << (ulStream - 1) ); + + } + + /* Clear the entry. */ + pulTsstAlloc[ ulTimeslot ] &= ~(0x1 << ulStream); + } + + /*======================================================================*/ + + return ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseTsst + +Description: Releases a TSST. + + If f_usTsstListIndex is set to cOCT6100_INVALID_INDEX, the API + will assume that no TSST list entry was reserved for this TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This tsst is used to keep + the present state of the chip and all its resources. + +f_ulNumTssts Number of TSSTs to be released. +f_ulStream Stream component of the TDM TSST. +f_ulTimeslot Timeslot component of the TDM TSST. +f_ulDirection Whether the TSST is an input TSST or output TSST. +f_usTsstListIndex Index in the TSST list of the current entry. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseTsst +UINT32 Oct6100ApiReleaseTsst( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulTimeslot, + IN UINT32 f_ulStream, + IN UINT32 f_ulNumTsst, + IN UINT32 f_ulDirection, + IN UINT16 f_usTsstListIndex) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PUINT32 pulTsstAlloc; + PVOID pTsstListAlloc; + UINT32 ulResult; + UINT32 ulStream; + UINT32 ulTimeslot; + + /* Get local pointer to shared portion of API instance structure. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + if ( f_usTsstListIndex != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_TSST_LIST_ALLOC_PNT( pSharedInfo, pTsstListAlloc ) + + ulResult = OctapiLlmAllocDealloc( pTsstListAlloc, f_usTsstListIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_53; + } + } + + mOCT6100_GET_TSST_ALLOC_PNT( f_pApiInstance->pSharedInfo, pulTsstAlloc ); + + /*==================================================================================*/ + /* Now make the proper conversion to obtain the TSST value. */ + + /* Save the timeslot and stream value received. */ + ulStream = f_ulStream; + ulTimeslot = f_ulTimeslot; + + /* Set the TSST index associated to this stream, timeslot combination. */ + if ( pSharedInfo->ChipConfig.aulTdmStreamFreqs[ f_ulStream / 4 ] == cOCT6100_TDM_STREAM_FREQ_16MHZ ) + { + if ( f_ulDirection == cOCT6100_INPUT_TSST ) + { + ulStream = f_ulStream + ( f_ulTimeslot % 2 ) * 16; + ulTimeslot = f_ulTimeslot / 2; + } + else /* f_ulDirection == cOCT6100_OUTPUT_TSST */ + { + ulStream = ( f_ulStream - 16 ) + ( f_ulTimeslot % 2 ) * 16; + + if ( f_ulStream < 28 && ((f_ulTimeslot % 2) == 1) ) + { + ulTimeslot = ((f_ulTimeslot / 2) + 4) % 128; + } + else + { + ulTimeslot = f_ulTimeslot / 2 ; + } + } + } + + /* Get local pointer to TSST's entry in allocation table. */ + switch ( pSharedInfo->ChipConfig.aulTdmStreamFreqs[ ulStream / 4 ] ) + { + case cOCT6100_TDM_STREAM_FREQ_2MHZ: + ulTimeslot *= 4; + break; + case cOCT6100_TDM_STREAM_FREQ_4MHZ: + ulTimeslot *= 2; + break; + case cOCT6100_TDM_STREAM_FREQ_8MHZ: + ulTimeslot *= 1; + break; + case cOCT6100_TDM_STREAM_FREQ_16MHZ: + ulTimeslot *= 1; + break; + default: + return cOCT6100_ERR_FATAL_DE; + } + + /* Check if entry is actualy reserved. */ + if ( ((pulTsstAlloc[ ulTimeslot ] >> ulStream) & 0x1) != 0x1 ) + return cOCT6100_ERR_FATAL_55; + + /*==================================================================================*/ + + /* Clear the entry. */ + pulTsstAlloc[ ulTimeslot ] &= ~(0x1 << ulStream); + + /* Check and release the associated TSST if required. */ + if ( f_ulNumTsst == 2 ) + { + /* Check if entry is actualy reserved. */ + if ( ((pulTsstAlloc[ ulTimeslot ] >> ( ulStream - 1)) & 0x1) != 0x1 ) + return cOCT6100_ERR_FATAL_54; + + /* Clear the entry. */ + pulTsstAlloc[ ulTimeslot ] &= ~(0x1 << (ulStream - 1)); + + } + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_user.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_user.c new file mode 100644 index 0000000..9d0e317 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_user.c @@ -0,0 +1,508 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_user.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the functions provided by the user. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 28 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + + +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_errors.h" + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserGetTime + +Description: Returns the system time in us. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pTime Pointer to structure in which the time is returned. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserGetTime +UINT32 Oct6100UserGetTime( + IN OUT tPOCT6100_GET_TIME f_pTime ) +{ + + return cOCT6100_ERR_OK; +} +#endif + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserMemSet + +Description: Sets f_ulLength bytes pointed to by f_pAddress to f_ulPattern. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pAddress Address in host memory where data should be set. +f_ulPattern Pattern to apply at the address. This value will never + exceed 0xFF. +f_ulLength Length in bytes to set. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserMemSet +UINT32 Oct6100UserMemSet( + IN PVOID f_pAddress, + IN UINT32 f_ulPattern, + IN UINT32 f_ulLength ) +{ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserMemCopy + +Description: Copy f_ulLength bytes from f_pSource to f_pDestination. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pDestination Host data destination address. +f_pSource Host data source address. +f_ulLength Length in bytes to copy. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserMemCopy +UINT32 Oct6100UserMemCopy( + IN PVOID f_pDestination, + IN const void *f_pSource, + IN UINT32 f_ulLength ) +{ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserCreateSerializeObject + +Description: Creates a serialization object. The serialization object is + seized via the Oct6100UserSeizeSerializeObject function. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pCreate Pointer to structure in which the serialization object's + handle is returned. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserCreateSerializeObject +UINT32 Oct6100UserCreateSerializeObject( + IN OUT tPOCT6100_CREATE_SERIALIZE_OBJECT f_pCreate ) +{ + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDestroySerializeObject + +Description: Destroys the indicated serialization object. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pDestroy Pointer to structure containing the handle of the + serialization object. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDestroySerializeObject +UINT32 Oct6100UserDestroySerializeObject( + IN tPOCT6100_DESTROY_SERIALIZE_OBJECT f_pDestroy ) +{ + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserSeizeSerializeObject + +Description: Seizes the indicated serialization object. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pSeize Pointer to structure containing the handle of the + serialization object. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserSeizeSerializeObject +UINT32 Oct6100UserSeizeSerializeObject( + IN tPOCT6100_SEIZE_SERIALIZE_OBJECT f_pSeize ) +{ + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserReleaseSerializeObject + +Description: Releases the indicated serialization object. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pRelease Pointer to structure containing the handle of the + serialization object. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserReleaseSerializeObject +UINT32 Oct6100UserReleaseSerializeObject( + IN tPOCT6100_RELEASE_SERIALIZE_OBJECT f_pRelease ) +{ + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDriverWriteApi + +Description: Performs a write access to the chip. This function is + accessible only from the API code entity (i.e. not from the + APIMI code entity). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pWriteParams Pointer to structure containing the Params to the + write function. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDriverWriteApi +UINT32 Oct6100UserDriverWriteApi( + IN tPOCT6100_WRITE_PARAMS f_pWriteParams ) +{ + + + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDriverWriteOs + +Description: Performs a write access to the chip. This function is + accessible only from the APIMI code entity (i.e. not from the + API code entity). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pWriteParams Pointer to structure containing the Params to the + write function. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDriverWriteOs +UINT32 Oct6100UserDriverWriteOs( + IN tPOCT6100_WRITE_PARAMS f_pWriteParams ) +{ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDriverWriteSmearApi + +Description: Performs a series of write accesses to the chip. The same data + word is written to a series of addresses. The writes begin at + the start address, and the address is incremented by the + indicated amount for each subsequent write. This function is + accessible only from the API code entity (i.e. not from the + APIMI code entity). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pSmearParams Pointer to structure containing the parameters to the + write smear function. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDriverWriteSmearApi +UINT32 Oct6100UserDriverWriteSmearApi( + IN tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams ) +{ + + + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDriverWriteSmearOs + +Description: Performs a series of write accesses to the chip. The same data + word is written to a series of addresses. The writes begin at + the start address, and the address is incremented by the + indicated amount for each subsequent write. This function is + accessible only from the APIMI code entity (i.e. not from the + API code entity). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pSmearParams Pointer to structure containing the parameters to the + write smear function. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDriverWriteSmearOs +UINT32 Oct6100UserDriverWriteSmearOs( + IN tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams ) +{ + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDriverWriteBurstApi + +Description: Performs a series of write accesses to the chip. An array of + data words is written to a series of consecutive addresses. + The writes begin at the start address with element 0 of the + provided array as the data word. The address is incremented by + two for each subsequent write. This function is accessible only + from the API code entity (i.e. not from the APIMI code entity). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pBurstParams Pointer to structure containing the parameters to the + write burst function. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDriverWriteBurstApi +UINT32 Oct6100UserDriverWriteBurstApi( + IN tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams ) +{ + + + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDriverWriteBurstOs + +Description: Performs a series of write accesses to the chip. An array of + data words is written to a series of consecutive addresses. + The writes begin at the start address with element 0 of the + provided array as the data word. The address is incremented by + two for each subsequent write. This function is accessible only + from the API code entity (i.e. not from the APIMI code entity). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pBurstParams Pointer to structure containing the parameters to the + write burst function. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDriverWriteBurstOs +UINT32 Oct6100UserDriverWriteBurstOs( + IN tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams ) +{ + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDriverReadApi + +Description: Performs a read access to the chip. This function is accessible + only from the API code entity (i.e. not from the APIMI code + entity). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pReadParams Pointer to structure containing the parameters to the + read function. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDriverReadApi +UINT32 Oct6100UserDriverReadApi( + IN OUT tPOCT6100_READ_PARAMS f_pReadParams ) +{ + + + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDriverReadOs + +Description: Performs a read access to the chip. This function is accessible + only from the APIMI code entity (i.e. not from the API code + entity). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pReadParams Pointer to structure containing the parameters to the + read function. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDriverReadOs +UINT32 Oct6100UserDriverReadOs( + IN OUT tPOCT6100_READ_PARAMS f_pReadParams ) +{ + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDriverReadBurstApi + +Description: Performs a burst of read accesses to the chip. The first read + is performed at the start address, and the address is + incremented by two for each subsequent read. The data is + retunred in an array provided by the user. This function is + accessible only from the API code entity (i.e. not from the + APIMI code entity). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pBurstParams Pointer to structure containing the parameters to the + read burst function. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDriverReadBurstApi +UINT32 Oct6100UserDriverReadBurstApi( + IN OUT tPOCT6100_READ_BURST_PARAMS f_pBurstParams ) +{ + + + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDriverReadBurstOs + +Description: Performs a burst of read accesses to the chip. The first read + is performed at the start address, and the address is + incremented by two for each subsequent read. The data is + retunred in an array provided by the user. This function is + accessible only from the APIMI code entity (i.e. not from the + API code entity). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pBurstParams Pointer to structure containing the parameters to the + read burst function. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDriverReadBurstOs +UINT32 Oct6100UserDriverReadBurstOs( + IN OUT tPOCT6100_READ_BURST_PARAMS f_pBurstParams ) +{ + + + return cOCT6100_ERR_OK; +} +#endif + + + + + + + diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_apimi/oct6100_mask_interrupts.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_apimi/oct6100_mask_interrupts.c new file mode 100644 index 0000000..a93db97 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_apimi/oct6100_mask_interrupts.c @@ -0,0 +1,116 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_mask_interrupts.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the mask interrupts function. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 8 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "oct6100api/oct6100_apimi.h" +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_defines.h" + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100InterruptMask + +Description: The function is used to mask out the interrupt pin of the chip. + This function is used when a deferred procedure call treats the + interrupt (new interrupts must not be generated until the + signaled interrupt is treated). Which chip is to have its + interrupts masked is determined by the mask structure, + f_pInterruptMask. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pInterruptMask Pointer to the interrupt masking structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100InterruptMaskDef( + OUT tPOCT6100_INTERRUPT_MASK f_pInterruptMask ) +{ + f_pInterruptMask->ulUserChipIndex = cOCT6100_INVALID_VALUE; + f_pInterruptMask->pProcessContext = NULL; + + + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100InterruptMask( + IN tPOCT6100_INTERRUPT_MASK f_pInterruptMask ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 result; + UINT16 usReadData; + + /* Determine if the chip's interrupt pin is active.*/ + ReadParams.ulReadAddress = 0x210; + ReadParams.pusReadData = &usReadData; + ReadParams.pProcessContext = f_pInterruptMask->pProcessContext; + + ReadParams.ulUserChipId = f_pInterruptMask->ulUserChipIndex; + + result = Oct6100UserDriverReadOs( &ReadParams ); + if ( result != cOCT6100_ERR_OK ) + return cOCT6100_ERR_INTRPTS_RW_ERROR; + + if ( (usReadData & 0xFFFF) != 0 ) + { + /* Chip's interrupt pin is active, so mask interrupt pin. */ + ReadParams.ulReadAddress = 0x214; + result = Oct6100UserDriverReadOs( &ReadParams ); + if ( result != cOCT6100_ERR_OK ) + return cOCT6100_ERR_INTRPTS_RW_ERROR; + + /* Determine if the chip's interrupt pin is active. */ + WriteParams.pProcessContext = f_pInterruptMask->pProcessContext; + + WriteParams.ulUserChipId = f_pInterruptMask->ulUserChipIndex; + WriteParams.ulWriteAddress = 0x214; + WriteParams.usWriteData = (UINT16)( (usReadData & 0xC000) | 0x3FFF ); + + result = Oct6100UserDriverWriteOs( &WriteParams ); + if ( result != cOCT6100_ERR_OK ) + return cOCT6100_ERR_INTRPTS_RW_ERROR; + + WriteParams.ulWriteAddress = 0x212; + WriteParams.usWriteData = 0x8000; + + result = Oct6100UserDriverWriteOs( &WriteParams ); + if ( result != cOCT6100_ERR_OK ) + return cOCT6100_ERR_INTRPTS_RW_ERROR; + + return cOCT6100_ERR_OK; + } + + return cOCT6100_ERR_INTRPTS_NOT_ACTIVE; +} diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_channel_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_channel_priv.h new file mode 100644 index 0000000..cd55191 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_channel_priv.h @@ -0,0 +1,529 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_channel_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_channel.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_channel_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 62 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHANNEL_PRIV_H__ +#define __OCT6100_CHANNEL_PRIV_H__ + + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +/* ECHO channel list pointer macros. */ +#define mOCT6100_GET_CHANNEL_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_CHANNEL )(( PUINT8 )pSharedInfo + pSharedInfo->ulChannelListOfst ); + +#define mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_CHANNEL )(( PUINT8 )pSharedInfo + pSharedInfo->ulChannelListOfst)) + ulIndex; + +#define mOCT6100_GET_CHANNEL_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulChannelAllocOfst); + +#define mOCT6100_GET_BIDIR_CHANNEL_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_BIDIR_CHANNEL )(( PUINT8 )pSharedInfo + pSharedInfo->ulBiDirChannelListOfst ); + +#define mOCT6100_GET_BIDIR_CHANNEL_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_BIDIR_CHANNEL )(( PUINT8 )pSharedInfo + pSharedInfo->ulBiDirChannelListOfst)) + ulIndex; + +#define mOCT6100_GET_BIDIR_CHANNEL_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulBiDirChannelAllocOfst ); + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_ECHO_CHAN_INDEX_ +{ + /* Index of the channel in the API echo channel list.*/ + UINT16 usEchoChanIndex; + + /* TSI chariot memory entry for the Rin/Rout stream. */ + UINT16 usRinRoutTsiMemIndex; + + /* TSI chariot memory entry for the Sin/Sout stream. */ + UINT16 usSinSoutTsiMemIndex; + + /* SSPX memory entry. */ + UINT16 usEchoMemIndex; + + /* TDM sample conversion control memory entry. */ + UINT16 usRinRoutConversionMemIndex; + UINT16 usSinSoutConversionMemIndex; + + /* Internal info for quick access to structures associated to this TSI cnct. */ + UINT16 usRinTsstIndex; + UINT16 usSinTsstIndex; + UINT16 usRoutTsstIndex; + UINT16 usSoutTsstIndex; + + /* Index of the phasing TSST */ + UINT16 usPhasingTsstIndex; + + UINT8 fSinSoutCodecActive; + UINT8 fRinRoutCodecActive; + + + /* Extended Tone Detection resources.*/ + UINT16 usExtToneChanIndex; + UINT16 usExtToneMixerIndex; + UINT16 usExtToneTsiIndex; +} tOCT6100_API_ECHO_CHAN_INDEX, *tPOCT6100_API_ECHO_CHAN_INDEX; + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetChannelsEchoSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100ApiChannelsEchoSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ChannelOpenSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_OPEN f_pChannelOpen ); + +UINT32 Oct6100ApiCheckChannelParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN OUT tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf ); + +UINT32 Oct6100ApiReserveChannelResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN OUT tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf ); + +UINT32 Oct6100ApiWriteChannelStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf ); + +UINT32 Oct6100ApiUpdateChannelEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf ); + +UINT32 Oct6100ChannelCloseSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_CLOSE f_pChannelClose ); + +UINT32 Oct6100ApiAssertChannelParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_CLOSE f_pChannelClose, + + IN OUT PUINT16 f_pusChanIndex ); + +UINT32 Oct6100ApiInvalidateChannelStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + + IN UINT16 f_usChanIndex ); + +UINT32 Oct6100ApiReleaseChannelResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChannelIndex ); + +UINT32 Oct6100ChannelModifySer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChannelModify ); + +UINT32 Oct6100ApiCheckChannelModify( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChannelModify, + IN OUT tPOCT6100_CHANNEL_OPEN f_pTempChanOpen, + OUT PUINT16 f_pusNewPhasingTsstIndex, + OUT PUINT16 f_pusChanIndex ); + +UINT32 Oct6100ApiModifyChannelResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChannelModify, + IN UINT16 f_usChanIndex, + OUT PUINT16 f_pusNewRinTsstIndex, + OUT PUINT16 f_pusNewSinTsstIndex, + OUT PUINT16 f_pusNewRoutTsstIndex, + OUT PUINT16 f_pusNewSoutTsstIndex ); + +UINT32 Oct6100ApiModifyChannelStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChannelModify, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usNewPhasingTsstIndex, + OUT PUINT8 f_pfSinSoutCodecActive, + OUT PUINT8 f_pfRinRoutCodecActive, + IN UINT16 f_usNewRinTsstIndex, + IN UINT16 f_uslNewSinTsstIndex, + IN UINT16 f_usNewRoutTsstIndex, + IN UINT16 f_usNewSoutTsstIndex ); + +UINT32 Oct6100ApiModifyChannelEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_MODIFY f_pChannelModify, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usNewPhasingTsstIndex, + IN UINT8 f_fSinSoutCodecActive, + IN UINT8 f_fRinRoutCodecActive, + IN UINT16 f_usNewRinTsstIndex, + IN UINT16 f_usNewSinTsstIndex, + IN UINT16 f_usNewRoutTsstIndex, + IN UINT16 f_usNewSoutTsstIndex ); + +UINT32 Oct6100ChannelBroadcastTsstAddSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd ); + +UINT32 Oct6100ApiCheckChanTsstAddParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstRemove, + OUT PUINT16 f_pusChanIndex ); + +UINT32 Oct6100ApiReserveTsstAddResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstRemove, + IN UINT16 f_usChanIndex, + OUT PUINT16 f_pusNewTsstIndex, + OUT PUINT16 f_pusNewTsstEntry ); + +UINT32 Oct6100ApiWriteTsstAddStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstRemove, + IN UINT16 f_usChanIndex, + IN UINT16 f_usNewTsstIndex ); + +UINT32 Oct6100ApiUpdateTsstAddChanEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstRemove, + IN UINT16 f_usChanIndex, + IN UINT16 f_usNewTsstIndex, + IN UINT16 f_usNewTsstEntry ); + +UINT32 Oct6100ChannelBroadcastTsstRemoveSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelTsstRemove); + +UINT32 Oct6100ApiAssertChanTsstRemoveParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelTsstRemove, + OUT PUINT16 f_pusChanIndex, + OUT PUINT16 f_pusTsstIndex, + OUT PUINT16 f_pusTsstEntry, + OUT PUINT16 f_pusPrevTsstEntry ); + +UINT32 Oct6100ApiInvalidateTsstRemoveStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChanIndex, + IN UINT16 f_usTsstIndex, + IN UINT32 f_ulPort, + IN BOOL f_fRemoveAll ); + +UINT32 Oct6100ApiReleaseTsstRemoveResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelTsstRemove, + IN UINT16 f_usChanIndex, + IN UINT16 f_usTsstIndex, + IN UINT16 f_usTsstEntry, + IN UINT16 f_usPrevTsstEntry ); + +UINT32 Oct6100ApiChannelGetStatsSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_STATS f_pChannelStats ); + +UINT32 Oct6100ApiReserveEchoEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusEchoIndex ); + +UINT32 Oct6100ApiReleaseEchoEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEchoChanIndex ); + +UINT32 Oct6100ApiCheckTdmConfig( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_TDM f_pTdmConfig ); + +UINT32 Oct6100ApiCheckVqeConfig( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN BOOL f_fEnableToneDisabler ); + +UINT32 Oct6100ApiCheckCodecConfig( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_CODEC f_pCodecConfig, + IN UINT32 f_ulDecoderNumTssts, + OUT PUINT16 f_pusPhasingTsstIndex ); + +UINT32 Oct6100ApiWriteInputTsstControlMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsstIndex, + IN UINT16 f_usTsiMemIndex, + IN UINT32 f_ulTsstInputLaw ); + +UINT32 Oct6100ApiWriteOutputTsstControlMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsstIndex, + IN UINT32 f_ulAdpcmNibblePosition, + IN UINT32 f_ulNumTssts, + IN UINT16 f_usTsiMemIndex ); + +UINT32 Oct6100ApiWriteEncoderMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulEncoderIndex, + IN UINT32 f_ulCompType, + IN UINT16 f_usTsiMemIndex, + IN UINT32 f_ulEnableSilenceSuppression, + IN UINT32 f_ulAdpcmNibblePosition, + IN UINT16 f_usPhasingTsstIndex, + IN UINT32 f_ulPhasingType, + IN UINT32 f_ulPhase ); + +UINT32 Oct6100ApiWriteDecoderMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usDecoderIndex, + IN UINT32 f_ulCompType, + IN UINT16 f_usTsiMemIndex, + IN UINT32 f_ulPcmLaw, + IN UINT32 f_ulAdpcmNibblePosition ); + + +UINT32 Oct6100ApiClearConversionMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usConversionMemIndex ); + +UINT32 Oct6100ApiWriteVqeMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fClearPlayoutPointers, + IN BOOL f_fModifyOnly ); + +UINT32 Oct6100ApiWriteVqeNlpMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fClearPlayoutPointers, + IN BOOL f_fModifyOnly ); + +UINT32 Oct6100ApiWriteVqeAfMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fClearPlayoutPointers, + IN BOOL f_fModifyOnly ); + +UINT32 Oct6100ApiWriteEchoMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_TDM f_pTdmConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usEchoIndex, + IN UINT16 f_usRinRoutTsiIndex, + IN UINT16 f_usSinSoutTsiIndex ); + +UINT32 Oct6100ApiUpdateOpenStruct( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChanModify, + IN OUT tPOCT6100_CHANNEL_OPEN f_pChanOpen, + IN tPOCT6100_API_CHANNEL f_pChanEntry ); + + + + + +UINT32 Oct6100ApiRetrieveNlpConfDword( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_CHANNEL f_pChanEntry, + IN UINT32 f_ulAddress, + OUT PUINT32 f_pulConfigDword ); + +UINT32 Oct6100ApiSaveNlpConfDword( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_CHANNEL f_pChanEntry, + IN UINT32 f_ulAddress, + IN UINT32 f_ulConfigDword ); + +UINT32 Oct6100ChannelCreateBiDirSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT IN OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir ); + +UINT32 Oct6100ApiCheckChannelCreateBiDirParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir, + OUT PUINT16 f_pusFirstChanIndex, + OUT PUINT16 f_pusFirstChanExtraTsiIndex, + OUT PUINT16 f_pusFirstChanSinCopyEventIndex, + OUT PUINT16 f_pusSecondChanIndex, + OUT PUINT16 f_pusSecondChanExtraTsiIndex, + OUT PUINT16 f_pusSecondChanSinCopyEventIndex + + ); + +UINT32 Oct6100ApiReserveChannelCreateBiDirResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + + OUT PUINT16 f_pusBiDirChanIndex, + IN OUT PUINT16 f_pusFirstChanExtraTsiIndex, + IN OUT PUINT16 f_pusFirstChanSinCopyEventIndex, + OUT PUINT16 f_pusFirstChanSoutCopyEventIndex, + IN OUT PUINT16 f_pusSecondChanExtraTsiIndex, + IN OUT PUINT16 f_pusSecondChanSinCopyEventIndex, + OUT PUINT16 f_pusSecondChanSoutCopyEventIndex ); + +UINT32 Oct6100ApiWriteChannelCreateBiDirStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + + IN UINT16 f_usFirstChanIndex, + IN UINT16 f_usFirstChanExtraTsiIndex, + IN UINT16 f_usFirstChanSinCopyEventIndex, + IN UINT16 f_usFirstChanSoutCopyEventIndex, + IN UINT16 f_usSecondChanIndex, + IN UINT16 f_usSecondChanExtraTsiIndex, + IN UINT16 f_usSecondChanSinCopyEventIndex, + IN UINT16 f_usSecondChanSoutCopyEventIndex ); + +UINT32 Oct6100ApiUpdateBiDirChannelEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir, + IN UINT16 f_usBiDirChanIndex, + IN UINT16 f_usFirstChanIndex, + IN UINT16 f_usFirstChanExtraTsiIndex, + IN UINT16 f_usFirstChanSinCopyEventIndex, + IN UINT16 f_usFirstChanSoutCopyEventIndex, + IN UINT16 f_usSecondChanIndex, + IN UINT16 f_usSecondChanExtraTsiIndex, + IN UINT16 f_usSecondChanSinCopyEventIndex, + IN UINT16 f_usSecondChanSoutCopyEventIndex ); + +UINT32 Oct6100ChannelDestroyBiDirSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir ); + +UINT32 Oct6100ApiAssertDestroyBiDirChanParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir, + IN OUT PUINT16 f_pusBiDirChanIndex, + + IN OUT PUINT16 f_pusFirstChanIndex, + IN OUT PUINT16 f_pusSecondChanIndex ); + +UINT32 Oct6100ApiInvalidateBiDirChannelStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + + IN UINT16 f_usFirstChanIndex, + IN UINT16 f_usSecondChanIndex ); + +UINT32 Oct6100ApiReleaseBiDirChannelResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBiDirChanIndex, + + IN UINT16 f_usFirstChanIndex, + IN UINT16 f_usSecondChanIndex ); + +UINT32 Oct6100ApiWriteDebugChanMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_TDM f_pTdmConfig, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN UINT16 f_usRinRoutTsiIndex, + IN UINT16 f_usSinSoutTsiIndex ); + +UINT32 Oct6100ApiDebugChannelOpen( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiMutePorts( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEchoIndex, + IN UINT16 f_usRinTsstIndex, + IN UINT16 f_usSinTsstIndex, + IN BOOL f_fCheckBridgeIndex ); + +UINT32 Oct6100ApiSetChannelLevelControl( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fClearAlcHlcStatusBit ); + +UINT32 Oct6100ApiSetChannelTailConfiguration( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fModifyOnly ); + +UINT32 Oct6100ChannelMuteSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MUTE f_pChannelMute ); + +UINT32 Oct6100ApiAssertChannelMuteParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MUTE f_pChannelMute, + OUT PUINT16 f_pusChanIndex, + OUT PUINT16 f_pusPorts ); + +UINT32 Oct6100ChannelUnMuteSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute ); + +UINT32 Oct6100ApiAssertChannelUnMuteParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute, + OUT PUINT16 f_pusChanIndex, + OUT PUINT16 f_pusPorts ); + +UINT32 Oct6100ApiMuteSinWithFeatures( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChanIndex, + IN BOOL f_fEnableSinWithFeatures ); + +UINT32 Oct6100ApiMuteChannelPorts( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChanIndex, + IN UINT16 f_usPortMask, + IN BOOL f_fMute ); + +INT32 Oct6100ApiOctFloatToDbEnergyByte( + IN UINT8 x ); + +INT32 Oct6100ApiOctFloatToDbEnergyHalf( + IN UINT16 x ); + +UINT16 Oct6100ApiDbAmpHalfToOctFloat( + IN INT32 x ); + +#endif /* __OCT6100_CHANNEL_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_chip_open_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_chip_open_priv.h new file mode 100644 index 0000000..46a13e3 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_chip_open_priv.h @@ -0,0 +1,264 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_open_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_chip_open.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_chip_open_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 63 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHIP_OPEN_PRIV_H__ +#define __OCT6100_CHIP_OPEN_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_INSTANCE_SIZES_ +{ + /* Each of the following elements indicates the size of the instance memory */ + /* needed by the corresponding API module. All sizes are in bytes. */ + UINT32 ulChannelList; + UINT32 ulChannelAlloc; + + UINT32 ulTsiCnctList; + UINT32 ulTsiCnctAlloc; + + UINT32 ulMixerEventList; + UINT32 ulMixerEventAlloc; + + UINT32 ulBiDirChannelList; + UINT32 ulBiDirChannelAlloc; + + UINT32 ulAdpcmChannelList; + UINT32 ulAdpcmChannelAlloc; + + UINT32 ulSoftBufPlayoutEventsBuffer; + + UINT32 ulCopyEventList; + UINT32 ulCopyEventAlloc; + + UINT32 ulConfBridgeList; + UINT32 ulConfBridgeAlloc; + + UINT32 ulFlexConfParticipantsList; + UINT32 ulFlexConfParticipantsAlloc; + + UINT32 ulPlayoutBufList; + UINT32 ulPlayoutBufAlloc; + UINT32 ulPlayoutBufMemoryNodeList; + + + + UINT32 ulSoftToneEventsBuffer; + + UINT32 ulPhasingTsstList; + UINT32 ulPhasingTsstAlloc; + + UINT32 ulConversionMemoryAlloc; + + UINT32 ulTsiMemoryAlloc; + UINT32 ulTsstAlloc; + + UINT32 ulTsstEntryList; + UINT32 ulTsstEntryAlloc; + + UINT32 ulRemoteDebugList; + UINT32 ulRemoteDebugTree; + UINT32 ulRemoteDebugPktCache; + UINT32 ulRemoteDebugDataBuf; + + /* Memory consumed by static members of API instance. */ + UINT32 ulApiInstStatic; + + /* Total memory size for API instance. */ + UINT32 ulApiInstTotal; + +} tOCT6100_API_INSTANCE_SIZES, *tPOCT6100_API_INSTANCE_SIZES; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiCheckChipConfiguration( + IN tPOCT6100_CHIP_OPEN f_pOpenChip ); + +UINT32 Oct6100ApiCheckImageFileHeader( + IN tPOCT6100_CHIP_OPEN f_pChipOpen ); + +UINT32 Oct6100ApiCopyChipConfiguration( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHIP_OPEN f_pOpenChip ); + +UINT32 Oct6100ApiInitializeMiscellaneousVariables( + IN OUT tPOCT6100_INSTANCE_API f_pInstance ); + +UINT32 Oct6100ApiCalculateInstanceSizes( + IN OUT tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstanceSizes ); + +UINT32 Oct6100ApiAllocateInstanceMemory( + IN OUT tPOCT6100_INSTANCE_API f_pInstance, + IN tPOCT6100_API_INSTANCE_SIZES f_pInstanceSizes ); + +UINT32 Oct6100ApiInitializeInstanceMemory( + IN OUT tPOCT6100_INSTANCE_API f_pInstance ); + +UINT32 Oct6100ApiGetChipRevisionNum( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiMapExternalMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiDecodeKeyAndBist( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiBootFc2Pll( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiProgramFc1Pll( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiBootFc1Pll( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiWriteH100Registers( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiExternalMemoryBist( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiExternalMemoryInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiLoadImage( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiCpuRegisterBist( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiBootSdram( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiEnableClocks( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiProgramNLP( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiSetH100Register( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiWriteMiscellaneousRegisters( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT16 Oct6100ApiGenerateNumber( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulIndex, + IN UINT32 f_ulDataMask ); + +UINT32 Oct6100ApiRandomMemoryWrite( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulMemBase, + IN UINT32 f_ulMemSize, + IN UINT32 f_ulNumDataBits, + IN UINT32 f_ulNumAccesses, + IN UINT32 f_ulErrorCode ); + +UINT32 Oct6100ApiUserIoTest( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiCreateSerializeObjects( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulUserChipId ); + +UINT32 Oct6100ApiDestroySerializeObjects( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiRunEgo( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN BOOL f_fStoreFlag, + IN UINT32 f_ulNumEntry, + OUT PUINT32 f_aulEntry ); + +UINT32 Oct6100ApiCreateEgoEntry( + IN OUT UINT32 f_ulExternalAddress, + IN UINT32 f_ulInternalAddress, + IN UINT32 f_ulNumBytes, + IN UINT32 f_aulEntry[ 2 ] ); + + + + + +UINT32 Oct6100ApiInitChannels( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiInitMixer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiInitRecordResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100FreeResourcesSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_FREE_RESOURCES f_pFreeResources ); + +UINT32 Oct6100ProductionBistSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_PRODUCTION_BIST f_pProductionBist ); + +UINT32 Oct6100ApiProductionCrc( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN PUINT32 f_pulMessage, + IN UINT32 f_ulMessageLength, + OUT PUINT32 f_pulCrcResult ); + +UINT32 Oct6100ApiReadCapacity( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins ); + +UINT32 Oct6100ApiCpuRegisterBistReadCap( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins ); + +UINT32 Oct6100ApiBootFc2PllReadCap( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins ); + +UINT32 Oct6100ApiProgramFc1PllReadCap( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins ); + +UINT32 Oct6100ApiInitToneInfo( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiClearInterrupts( + IN tPOCT6100_INSTANCE_API f_pApiInstance ); +#endif /* __OCT6100_CHIP_OPEN_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_chip_stats_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_chip_stats_priv.h new file mode 100644 index 0000000..6c36163 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_chip_stats_priv.h @@ -0,0 +1,55 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_stats_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_chip_stats.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_chip_stats_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 8 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHIP_STATS_PRIV_H__ +#define __OCT6100_CHIP_STATS_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiChipStatsSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ChipGetStatsSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT tPOCT6100_CHIP_STATS f_pChipStats ); + +#endif /* __OCT6100_CHIP_STATS_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_conf_bridge_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_conf_bridge_priv.h new file mode 100644 index 0000000..071e645 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_conf_bridge_priv.h @@ -0,0 +1,318 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_conf_bridge_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_conf_bridge.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_conf_bridge_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 30 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CONF_BRIDGE_PRIV_H__ +#define __OCT6100_CONF_BRIDGE_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +#define mOCT6100_GET_CONF_BRIDGE_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_CONF_BRIDGE )(( PUINT8 )pSharedInfo + pSharedInfo->ulConfBridgeListOfst); + +#define mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_CONF_BRIDGE )(( PUINT8 )pSharedInfo + pSharedInfo->ulConfBridgeListOfst)) + ulIndex; + +#define mOCT6100_GET_CONF_BRIDGE_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulConfBridgeAllocOfst); + +#define mOCT6100_GET_FLEX_CONF_PARTICIPANT_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_FLEX_CONF_PARTICIPANT )(( PUINT8 )pSharedInfo + pSharedInfo->ulFlexConfParticipantListOfst); + +#define mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_FLEX_CONF_PARTICIPANT )(( PUINT8 )pSharedInfo + pSharedInfo->ulFlexConfParticipantListOfst)) + ulIndex; + +#define mOCT6100_GET_FLEX_CONF_PARTICIPANT_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulFlexConfParticipantAllocOfst); + + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetConfBridgeSwSizes( + IN OUT tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100ApiConfBridgeSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst ); + +UINT32 Oct6100ConfBridgeOpenSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ); + +UINT32 Oct6100ApiCheckBridgeParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ); + +UINT32 Oct6100ApiReserveBridgeResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + OUT PUINT16 f_pusBridgeIndex ); + +UINT32 Oct6100ApiUpdateBridgeEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen, + IN UINT16 f_usBridgeIndex ); + +UINT32 Oct6100ConfBridgeCloseSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose ); + +UINT32 Oct6100ApiAssertBridgeParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose, + OUT PUINT16 f_pusBridgeIndex ); + +UINT32 Oct6100ApiReleaseBridgeResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usBridgeIndex ); + +UINT32 Oct6100ConfBridgeChanAddSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CHAN_ADD f_pConfBridgeAdd ); + +UINT32 Oct6100ApiCheckBridgeAddParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CHAN_ADD f_pConfBridgeAdd, + OUT PUINT16 f_pusBridgeIndex, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT8 f_pfMute, + OUT PUINT32 f_pulInputPort, + OUT PUINT8 f_pfFlexibleConfBridge, + OUT PUINT32 f_pulListenerMaskIndex, + OUT PUINT32 f_pulListenerMask, + OUT PUINT8 f_pfTap, + OUT PUINT16 f_pusTapChannelIndex ); + +UINT32 Oct6100ApiReserveBridgeAddResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChanIndex, + IN UINT32 f_ulInputPort, + IN UINT8 f_fFlexibleConfBridge, + IN UINT32 f_ulListenerMaskIndex, + IN UINT32 f_ulListenerMask, + IN UINT8 f_fTap, + OUT PUINT16 f_pusLoadEventIndex, + OUT PUINT16 f_pusSubStoreEventIndex, + OUT PUINT16 f_pusCopyEventIndex, + OUT PUINT16 f_pusTapBridgeIndex ); + +UINT32 Oct6100ApiBridgeEventAdd( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChannelIndex, + IN UINT8 f_fFlexibleConfBridge, + IN UINT16 f_usLoadEventIndex, + IN UINT16 f_usSubStoreEventIndex, + IN UINT16 f_usCopyEventIndex, + IN UINT32 f_ulInputPort, + IN UINT8 f_fMute, + IN UINT32 f_ulListenerMaskIndex, + IN UINT32 f_ulListenerMask, + IN UINT8 f_fTap, + IN UINT16 f_usTapBridgeIndex, + IN UINT16 f_usTapChanIndex ); + +UINT32 Oct6100ApiBridgeAddParticipantToChannel( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usSourceChannelIndex, + IN UINT16 f_usDestinationChannelIndex, + IN UINT16 f_usLoadOrAccumulateEventIndex, + IN UINT16 f_usStoreEventIndex, + IN UINT16 f_usCopyEventIndex, + IN UINT32 f_ulSourceInputPort, + IN UINT32 f_ulDestinationInputPort ); + +UINT32 Oct6100ConfBridgeChanRemoveSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove ); + +UINT32 Oct6100ApiCheckChanRemoveParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove, + OUT PUINT16 f_pusBridgeIndex, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT8 f_pfFlexibleConfBridge, + OUT PUINT8 f_pfTap, + OUT PUINT16 f_pusLoadEventIndex, + OUT PUINT16 f_pusSubStoreEventIndex, + OUT PUINT16 f_pusCopyEventIndex ); + +UINT32 Oct6100ApiReleaseChanEventResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChanIndex, + IN UINT8 f_fFlexibleConfBridge, + IN UINT16 f_usLoadEventIndex, + IN UINT16 f_usSubStoreEventIndex, + IN UINT16 f_usCopyEventIndex ); + +UINT32 Oct6100ApiBridgeEventRemove ( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChannelIndex, + IN UINT8 f_fFlexibleConfBridge, + IN UINT16 f_usLoadEventIndex, + IN UINT16 f_usSubStoreEventIndex, + IN UINT16 f_usCopyEventIndex, + IN UINT8 f_fTap ); + +UINT32 Oct6100ApiBridgeRemoveParticipantFromChannel( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usSourceChannelIndex, + IN UINT16 f_usDestinationChannelIndex, + IN UINT8 f_fRemovePermanently ); + +UINT32 Oct6100ConfBridgeChanMuteSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CHAN_MUTE f_pConfBridgeMute ); + +UINT32 Oct6100ApiUpdateBridgeMuteResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usChanIndex, + IN UINT16 f_usLoadEventIndex, + IN UINT16 f_usSubStoreEventIndex, + IN UINT8 f_fFlexibleConfBridge ); + +UINT32 Oct6100ApiCheckBridgeMuteParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CHAN_MUTE f_pConfBridgeMute, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT16 f_pusLoadEventIndex, + OUT PUINT16 f_pusSubStoreEventIndex, + OUT PUINT8 f_pfFlexibleConfBridge ); + +UINT32 Oct6100ConfBridgeChanUnMuteSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE f_pConfBridgeUnMute ); + +UINT32 Oct6100ApiCheckBridgeUnMuteParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE f_pConfBridgeUnMute, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT16 f_pusLoadEventIndex, + OUT PUINT16 f_pusSubStoreEventIndex, + OUT PUINT8 f_pfFlexibleConfBridge ); + +UINT32 Oct6100ApiUpdateBridgeUnMuteResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usChanIndex, + IN UINT16 f_usLoadEventIndex, + IN UINT16 f_usSubStoreEventIndex, + IN UINT8 f_fFlexibleConfBridge ); + +UINT32 Oct6100ConfBridgeDominantSpeakerSetSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET f_pConfBridgeDominantSpeaker ); + +UINT32 Oct6100ApiCheckBridgeDominantSpeakerParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET f_pConfBridgeDominantSpeaker, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT16 f_pusBridgeIndex ); + +UINT32 Oct6100ApiUpdateBridgeDominantSpeakerResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usChanIndex, + IN UINT16 f_usBridgeIndex ); + +UINT32 Oct6100ConfBridgeMaskChangeSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_MASK_CHANGE f_pConfBridgeMaskChange ); + +UINT32 Oct6100ApiCheckBridgeMaskChangeParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_MASK_CHANGE f_pConfBridgeMaskChange, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT16 f_pusBridgeIndex, + OUT PUINT32 f_pulNewParticipantMask ); + +UINT32 Oct6100ApiUpdateMaskModifyResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChanIndex, + IN UINT32 f_ulNewListenerMask ); + +UINT32 Oct6100ApiBridgeUpdateMask( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChanIndex, + IN UINT32 f_ulNewListenerMask ); + +UINT32 Oct6100ConfBridgeGetStatsSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_CONF_BRIDGE_STATS f_pConfBridgeStats ); + +UINT32 Oct6100ApiReserveBridgeEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + OUT PUINT16 f_pusConfBridgeIndex ); + +UINT32 Oct6100ApiReleaseBridgeEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usConfBridgeIndex ); + +UINT32 Oct6100ApiGetPrevLastSubStoreEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usBridgeFirstLoadEventPtr, + OUT PUINT16 f_pusLastSubStoreEventIndex ); + +UINT32 Oct6100ApiGetPreviousEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usStartIndex, + IN UINT16 f_usSearchedIndex, + IN UINT16 f_usLoopCnt, + OUT PUINT16 f_pusPreviousIndex ); + +UINT32 Oct6100ApiBridgeSetDominantSpeaker( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usChannelIndex, + IN UINT16 f_usDominantSpeakerIndex ); + +UINT32 Oct6100ApiReserveFlexConfParticipantEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + OUT PUINT16 f_pusParticipantIndex ); + +UINT32 Oct6100ApiReleaseFlexConfParticipantEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usParticipantIndex ); + +#endif /* __OCT6100_CONF_BRIDGE_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_debug_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_debug_priv.h new file mode 100644 index 0000000..44a9a21 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_debug_priv.h @@ -0,0 +1,58 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_debug_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_debug.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_debug_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 12 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_DEBUG_PRIV_H__ +#define __OCT6100_DEBUG_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + + +UINT32 Oct6100DebugSelectChannelSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_DEBUG_SELECT_CHANNEL f_pSelectDebugChan, + IN BOOL f_fCheckChannelRecording ); + +UINT32 Oct6100DebugGetDataSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_DEBUG_GET_DATA f_pGetData ); + +#endif /* __OCT6100_DEBUG_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_events_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_events_priv.h new file mode 100644 index 0000000..fd3980a --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_events_priv.h @@ -0,0 +1,82 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_events_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_events.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_events_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 14 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_EVENTS_PRIV_H__ +#define __OCT6100_EVENTS_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +#define mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftBuf ) \ + pSoftBuf = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->SoftBufs.ulToneEventBufferMemOfst ); + +#define mOCT6100_GET_BUFFER_PLAYOUT_EVENT_BUF_PNT( pSharedInfo, pSoftBuf ) \ + pSoftBuf = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferMemOfst ); + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetEventsSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100EventGetToneSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_EVENT_GET_TONE f_pEventGetTone ); + +UINT32 Oct6100ApiTransferToneEvents( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulResetBuf ); + + + +UINT32 Oct6100BufferPlayoutGetEventSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_GET_EVENT f_pBufPlayoutGetEvent ); + +UINT32 Oct6100BufferPlayoutTransferEvents( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulResetBuf ); + +UINT32 Oct6100BufferPlayoutCheckForSpecificEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulChannelPort, + IN BOOL f_fSaveToSoftBuffer, + OUT PBOOL f_pfEventDetected ); + +#endif /* __OCT6100_EVENTS_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_interrupts_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_interrupts_priv.h new file mode 100644 index 0000000..d29f1b0 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_interrupts_priv.h @@ -0,0 +1,158 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_interrupts_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_interrupts.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_interrupts_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 11 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_INTERRUPTS_PRIV_H__ +#define __OCT6100_INTERRUPTS_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +#define mOCT6100_GET_INTRPT_ENABLE_TIME( \ + ulRegMclkTimeHigh, \ + ulRegMclkTimeLow, \ + ulIntrptState, \ + ulIntrptEnableMclkHigh, \ + ulIntrptEnableMclkLow, \ + ulIntrptTimeoutMclk, \ + ulTimeDiff ) \ + if ( ulIntrptState == cOCT6100_INTRPT_WILL_TIMEOUT ) \ + { \ + ulIntrptEnableMclkLow = ulRegMclkTimeLow + ulIntrptTimeoutMclk; \ + if ( ulIntrptEnableMclkLow < ulRegMclkTimeLow ) \ + ulIntrptEnableMclkHigh = (ulRegMclkTimeHigh + 1) & 0xFF; \ + else \ + ulIntrptEnableMclkHigh = ulRegMclkTimeHigh; \ + \ + ulIntrptState = cOCT6100_INTRPT_IN_TIMEOUT; \ + } \ + \ + if ( ulIntrptEnableMclkLow < ulRegMclkTimeLow ) \ + { \ + ulTimeDiff = (cOCT6100_FFFFFFFF - ulRegMclkTimeLow - 1) + ulIntrptEnableMclkLow; \ + } \ + else \ + { \ + ulTimeDiff = ulIntrptEnableMclkLow - ulRegMclkTimeLow; \ + } + +#define mOCT6100_CHECK_INTRPT_TIMEOUT( \ + ulRegMclkTimePlus5MsHigh, \ + ulRegMclkTimePlus5MsLow, \ + ulIntrptDisableMclkHigh, \ + ulIntrptDisableMclkLow, \ + ulIntrptEnableMclkHigh, \ + ulIntrptEnableMclkLow, \ + ulIntrptState, \ + fIntrptChange ) \ + /* Branch depending on whether the disable time is lesser or greater than the timeout time. */ \ + if ( ulIntrptDisableMclkLow < ulIntrptEnableMclkLow ) \ + { \ + /* Disable period is over if mclk is greater than timeout time or less than disabled time. */ \ + if ( ulRegMclkTimePlus5MsLow > ulIntrptEnableMclkLow || \ + ulRegMclkTimePlus5MsLow < ulIntrptDisableMclkLow || \ + ulRegMclkTimePlus5MsHigh != ulIntrptEnableMclkHigh ) \ + { \ + fIntrptChange = TRUE; \ + ulIntrptState = cOCT6100_INTRPT_ACTIVE; \ + } \ + } \ + else \ + { \ + /* Disable period is over if mclk is lesser than disable time and greater than timeout. */ \ + if ( (ulRegMclkTimePlus5MsLow > ulIntrptEnableMclkLow && ulRegMclkTimePlus5MsLow < ulIntrptDisableMclkLow) || \ + (ulRegMclkTimePlus5MsHigh != ulIntrptDisableMclkHigh && ulRegMclkTimePlus5MsHigh != ulIntrptEnableMclkHigh) ) \ + { \ + fIntrptChange = TRUE; \ + ulIntrptState = cOCT6100_INTRPT_ACTIVE; \ + } \ + } + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiIsrSwInit( + IN tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiIsrHwInit( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_INTERRUPT_CONFIGURE f_pIntrptConfig ); + +UINT32 Oct6100InterruptConfigureSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_INTERRUPT_CONFIGURE f_pIntrptConfig, + IN BOOL f_fCheckParams ); + +UINT32 Oct6100ApiClearEnabledInterrupts( + IN tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100InterruptServiceRoutineSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + OUT tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ); + +UINT32 Oct6100ApiWriteIeRegs( + IN tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiReadIntrptRegs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + OUT tPOCT6100_INTERRUPT_FLAGS f_pIntFlags, + IN UINT32 f_ulRegister210h ); + +UINT32 Oct6100ApiUpdateIntrptStates( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + OUT tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ); + +UINT32 Oct6100ApiWriteIntrptRegs( + IN tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiReadChipMclkTime( + IN tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiUpdateIntrptTimeouts( + IN tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiScheduleNextMclkIntrpt( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulIntrptToSet ); + +UINT32 Oct6100ApiScheduleNextMclkIntrptSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiCheckProcessorState( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ); + +#endif /* __OCT6100_INTERRUPTS_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_memory_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_memory_priv.h new file mode 100644 index 0000000..77eed5e --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_memory_priv.h @@ -0,0 +1,97 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_memory_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_memory.c. All elements defined in this + file are for private usage of the API. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 17 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_MEMORY_PRIV_H__ +#define __OCT6100_MEMORY_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +/* TSI allocation pointer macros. */ +#define mOCT6100_GET_TSI_MEMORY_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulTsiMemoryAllocOfst ); + +/* Conversion memory allocation pointer macros. */ +#define mOCT6100_GET_CONVERSION_MEMORY_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulConversionMemoryAllocOfst ); + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetMemorySwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100ApiMemorySwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiBufferPlayoutMemorySwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiReserveBufferPlayoutMemoryNode( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT32 f_pulNewNode ); + +UINT32 Oct6100ApiReleaseBufferPlayoutMemoryNode( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulOldNode ); + +UINT32 Oct6100ApiReserveBufferPlayoutMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulSize, + OUT PUINT32 f_pulMallocAddress ); + +UINT32 Oct6100ApiReleaseBufferPlayoutMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulMallocAddress ); + +UINT32 Oct6100ApiReserveTsiMemEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusTsiMemIndex ); + +UINT32 Oct6100ApiReleaseTsiMemEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsiMemIndex ); + +UINT32 Oct6100ApiReserveConversionMemEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusConversionMemIndex ); + +UINT32 Oct6100ApiReleaseConversionMemEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usConversionMemIndex ); + +#endif /* __OCT6100_MEMORY_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_miscellaneous_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_miscellaneous_priv.h new file mode 100644 index 0000000..70d2fc0 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_miscellaneous_priv.h @@ -0,0 +1,277 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_miscellaneous_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_miscellaneous.c. All elements defined in + this file are for private usage of the API. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 20 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_MISCELLANEOUS_PRIV_H__ +#define __OCT6100_MISCELLANEOUS_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/*---------------------------------------------------------------------------*\ + Macros used to shell the user function calls. These macros are used to + assert that the user does not change any of the members of the function's + parameter structure, as required and indicated in the API specification. + Ofcourse, these macros make the code heavier and thus slower. That is why + there is a compile option for disabling the extra checking. These can be + very helpful tools in debugging. +\*---------------------------------------------------------------------------*/ + +#ifndef cOCT6100_REMOVE_USER_FUNCTION_CHECK +#define mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) \ +{ \ + PVOID _pProcessContext; \ + UINT32 _ulUserChipId; \ + UINT32 _ulWriteAddress; \ + UINT16 _usWriteData; \ + \ + /* Store the data that is to be passed to the user. */ \ + _pProcessContext = WriteParams.pProcessContext; \ + _ulUserChipId = WriteParams.ulUserChipId; \ + _ulWriteAddress = WriteParams.ulWriteAddress; \ + _usWriteData = WriteParams.usWriteData; \ + \ + /* Call user function. */ \ + ulResult = Oct6100UserDriverWriteApi( &WriteParams ); \ + \ + /* Check if user changed members of function's parameter structure. */ \ + if ( WriteParams.pProcessContext != _pProcessContext || \ + WriteParams.ulUserChipId != _ulUserChipId || \ + WriteParams.ulWriteAddress != _ulWriteAddress || \ + WriteParams.ulWriteAddress != _ulWriteAddress || \ + WriteParams.usWriteData != _usWriteData ) \ + ulResult = cOCT6100_ERR_FATAL_DRIVER_WRITE_API; \ +} +#else +#define mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) \ + ulResult = Oct6100UserDriverWriteApi( &WriteParams ); +#endif /* cOCT6100_REMOVE_USER_FUNCTION_CHECK */ + + +#ifndef cOCT6100_REMOVE_USER_FUNCTION_CHECK +#define mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ) \ +{ \ + PVOID _pProcessContext; \ + UINT32 _ulUserChipId; \ + UINT16 _usWriteData; \ + UINT32 _ulWriteLength; \ + \ + /* Store the data that is to be passed to the user. */ \ + _pProcessContext = SmearParams.pProcessContext; \ + _ulUserChipId = SmearParams.ulUserChipId; \ + _usWriteData = SmearParams.usWriteData; \ + _ulWriteLength = SmearParams.ulWriteLength; \ + \ + /* Call user function. */ \ + ulResult = Oct6100UserDriverWriteSmearApi( &SmearParams ); \ + \ + /* Check if user changed members of function's paraeter structure. */ \ + if ( SmearParams.pProcessContext != _pProcessContext || \ + SmearParams.ulUserChipId != _ulUserChipId || \ + SmearParams.usWriteData != _usWriteData || \ + SmearParams.ulWriteLength != _ulWriteLength) \ + ulResult = cOCT6100_ERR_FATAL_DRIVER_WRITE_SMEAR_API; \ +} +#else +#define mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ) \ + ulResult = Oct6100UserDriverWriteSmearApi( &SmearParams ); +#endif /* cOCT6100_REMOVE_USER_FUNCTION_CHECK */ + + +#ifndef cOCT6100_REMOVE_USER_FUNCTION_CHECK +#define mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ) \ +{ \ + PVOID _pProcessContext; \ + UINT32 _ulUserChipId; \ + UINT32 _ulWriteAddress; \ + PUINT16 _pusWriteData; \ + UINT32 _ulWriteLength; \ + \ + /* Store the data that is to be passed to the user. */ \ + _pProcessContext = BurstParams.pProcessContext; \ + _ulUserChipId = BurstParams.ulUserChipId; \ + _ulWriteAddress = BurstParams.ulWriteAddress; \ + _pusWriteData = BurstParams.pusWriteData; \ + _ulWriteLength = BurstParams.ulWriteLength; \ + \ + /* Call user function. */ \ + ulResult = Oct6100UserDriverWriteBurstApi( &BurstParams ); \ + \ + /* Check if user changed members of function's parameter structure. */ \ + if ( BurstParams.pProcessContext != _pProcessContext || \ + BurstParams.ulUserChipId != _ulUserChipId || \ + BurstParams.ulWriteAddress != _ulWriteAddress || \ + BurstParams.pusWriteData != _pusWriteData || \ + BurstParams.ulWriteLength != _ulWriteLength ) \ + ulResult = cOCT6100_ERR_FATAL_DRIVER_WRITE_BURST_API; \ +} +#else +#define mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ) \ + ulResult = Oct6100UserDriverWriteBurstApi( &BurstParams ); +#endif /* cOCT6100_REMOVE_USER_FUNCTION_CHECK */ + + +#ifndef cOCT6100_REMOVE_USER_FUNCTION_CHECK +#define mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) \ +{ \ + PVOID _pProcessContext; \ + UINT32 _ulUserChipId; \ + UINT32 _ulReadAddress; \ + PUINT16 _pusReadData; \ + \ + /* Store the data that is to be passed to the user. */ \ + _pProcessContext = ReadParams.pProcessContext; \ + _ulUserChipId = ReadParams.ulUserChipId; \ + _ulReadAddress = ReadParams.ulReadAddress; \ + _pusReadData = ReadParams.pusReadData; \ + \ + /* Call user function. */ \ + ulResult = Oct6100UserDriverReadApi( &ReadParams ); \ + \ + /* Check if user changed members of function's parameter structure. */ \ + if ( ReadParams.pProcessContext != _pProcessContext || \ + ReadParams.ulUserChipId != _ulUserChipId || \ + ReadParams.ulReadAddress != _ulReadAddress || \ + ReadParams.pusReadData != _pusReadData ) \ + ulResult = cOCT6100_ERR_FATAL_DRIVER_READ_API; \ +} +#else +#define mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) \ + ulResult = Oct6100UserDriverReadApi( &ReadParams ); +#endif /* cOCT6100_REMOVE_USER_FUNCTION_CHECK */ + + +#ifndef cOCT6100_REMOVE_USER_FUNCTION_CHECK +#define mOCT6100_DRIVER_READ_BURST_API( BurstParams, ulResult ) \ +{ \ + PVOID _pProcessContext; \ + UINT32 _ulUserChipId; \ + UINT32 _ulReadAddress; \ + PUINT16 _pusReadData; \ + UINT32 _ulReadLength; \ + \ + /* Store the data that is to be passed to the user. */ \ + _pProcessContext = BurstParams.pProcessContext; \ + _ulUserChipId = BurstParams.ulUserChipId; \ + _ulReadAddress = BurstParams.ulReadAddress; \ + _pusReadData = BurstParams.pusReadData; \ + _ulReadLength = BurstParams.ulReadLength; \ + \ + /* Call user function. */ \ + ulResult = Oct6100UserDriverReadBurstApi( &BurstParams ); \ + \ + /* Check if user changed members of function's parameter structure. */ \ + if ( BurstParams.pProcessContext != _pProcessContext || \ + BurstParams.ulUserChipId != _ulUserChipId || \ + BurstParams.ulReadAddress != _ulReadAddress || \ + BurstParams.pusReadData != _pusReadData || \ + BurstParams.ulReadLength != _ulReadLength ) \ + ulResult = cOCT6100_ERR_FATAL_DRIVER_READ_BURST_API; \ +} +#else +#define mOCT6100_DRIVER_READ_BURST_API( BurstParams, ulResult ) \ + ulResult = Oct6100UserDriverReadBurstApi( &BurstParams ); +#endif /* cOCT6100_REMOVE_USER_FUNCTION_CHECK */ + +#define mOCT6100_ASSIGN_USER_READ_WRITE_OBJ( f_pApiInst, Params ) + +#define mOCT6100_CREATE_FEATURE_MASK( f_ulFieldSize, f_ulFieldBitOffset, f_pulFieldMask ) \ +{ \ + (*f_pulFieldMask) = ( 1 << f_ulFieldSize ); \ + (*f_pulFieldMask) --; \ + (*f_pulFieldMask) <<= f_ulFieldBitOffset; \ +} + + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiWaitForTime( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_aulWaitTime[ 2 ] ); + +UINT32 Oct6100ApiWaitForPcRegisterBit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulPcRegAdd, + IN UINT32 f_ulPcBitNum, + IN UINT32 f_ulValue, + IN UINT32 f_ulTimeoutUs, + OUT PBOOL f_pfBitEqual ); + +UINT32 Oct6100ApiWriteDword( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulAddress, + IN UINT32 f_ulWriteData ); + +UINT32 Oct6100ApiReadDword( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulAddress, + OUT PUINT32 f_pulReadData ); + +VOID Oct6100ApiCreateFeatureMask( + IN UINT32 f_ulFieldSize, + IN UINT32 f_ulFieldBitOffset, + OUT PUINT32 f_pulFieldMask ); + +unsigned char const *Oct6100ApiStrStr( + IN unsigned char const *f_pszSource, + IN unsigned char const *f_pszString, + IN unsigned char const *f_pszLastCharPtr ); + +UINT32 Oct6100ApiStrLen( + IN unsigned char const *f_pszString ); + +UINT32 Oct6100ApiAsciiToHex( + IN UINT8 f_chCharacter, + IN PUINT32 f_pulValue ); + +UINT8 Oct6100ApiHexToAscii( + IN UINT32 f_ulNumber ); + +UINT32 Oct6100ApiRand( + IN UINT32 f_ulRange ); + +UINT32 oct6100_retrieve_nlp_conf_dword(tPOCT6100_INSTANCE_API f_pApiInst, + tPOCT6100_API_CHANNEL f_pChanEntry, + UINT32 f_ulAddress, + UINT32 *f_pulConfigDword); + +UINT32 oct6100_save_nlp_conf_dword(tPOCT6100_INSTANCE_API f_pApiInst, + tPOCT6100_API_CHANNEL f_pChanEntry, + UINT32 f_ulAddress, + UINT32 f_ulConfigDword); + +#endif /* __OCT6100_MISCELLANEOUS_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_mixer_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_mixer_priv.h new file mode 100644 index 0000000..b6a7a34 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_mixer_priv.h @@ -0,0 +1,150 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_mixer_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_mixer.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_mixer_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 18 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_MIXER_PRIV_H__ +#define __OCT6100_MIXER_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +#define mOCT6100_GET_MIXER_EVENT_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_MIXER_EVENT )(( PUINT8 )pSharedInfo + pSharedInfo->ulMixerEventListOfst); + +#define mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_MIXER_EVENT )(( PUINT8 )pSharedInfo + pSharedInfo->ulMixerEventListOfst)) + ulIndex; + +#define mOCT6100_GET_MIXER_EVENT_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulMixerEventAllocOfst); + +#define mOCT6100_GET_COPY_EVENT_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_COPY_EVENT )(( PUINT8 )pSharedInfo + pSharedInfo->ulCopyEventListOfst); + +#define mOCT6100_GET_COPY_EVENT_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_COPY_EVENT )(( PUINT8 )pSharedInfo + pSharedInfo->ulCopyEventListOfst)) + ulIndex; + +#define mOCT6100_GET_COPY_EVENT_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulCopyEventAllocOfst); + +/***************************** TYPES ***************************************/ + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetMixerSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100ApiMixerSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiMixerEventAdd( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEventIndex, + IN UINT16 f_usEventType, + IN UINT16 f_usDestinationChanIndex ); + +UINT32 Oct6100ApiMixerEventRemove( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEventIndex, + IN UINT16 f_usEventType ); + +UINT32 Oct6100MixerCopyEventCreateSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate ); + +UINT32 Oct6100ApiCheckCopyEventCreateParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate, + OUT PUINT16 f_pusSourceChanIndex, + OUT PUINT16 f_pusDestinationChanIndex ); + +UINT32 Oct6100ApiReserveCopyEventCreateResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusCopyEntryIndex, + IN OUT PUINT16 f_pusCopyEventIndex ); + +UINT32 Oct6100ApiWriteCopyEventCreateStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate, + IN UINT16 f_usMixerEventIndex, + IN UINT16 f_usSourceChanIndex, + IN UINT16 f_usDestinationChanIndex ); + +UINT32 Oct6100ApiUpdateCopyEventCreateEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate, + IN UINT16 f_usCopyEventIndex, + IN UINT16 f_usMixerEventIndex, + IN UINT16 f_usSourceChanIndex, + IN UINT16 f_usDestinationChanIndex ); + +UINT32 Oct6100MixerCopyEventDestroySer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy ); + +UINT32 Oct6100ApiAssertCopyEventDestroyParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy, + IN OUT PUINT16 f_pusCopyEventIndex, + IN OUT PUINT16 f_pusMixerEventIndex ); + +UINT32 Oct6100ApiInvalidateCopyEventStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usCopyEventIndex, + IN UINT16 f_usMixerEventIndex ); + +UINT32 Oct6100ApiReleaseCopyEventResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usCopyEventIndex, + IN UINT16 f_usMixerEventIndex ); + +UINT32 Oct6100ApiReserveMixerEventEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusEventIndex ); + +UINT32 Oct6100ApiReleaseMixerEventEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEventIndex ); + +UINT32 Oct6100ApiGetFreeMixerEventCnt( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT32 f_pulFreeEventCnt ); + +UINT32 Oct6100ApiReserveCopyEventEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusEventIndex ); + +UINT32 Oct6100ApiReleaseCopyEventEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEventIndex ); +#endif /* __OCT6100_MIXER_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_phasing_tsst_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_phasing_tsst_priv.h new file mode 100644 index 0000000..e17ab8b --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_phasing_tsst_priv.h @@ -0,0 +1,114 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_phasing_tsst_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_phasing_tsst.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_phasing_tsst_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 12 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_PHASING_TSST_PRIV_H__ +#define __OCT6100_PHASING_TSST_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +#define mOCT6100_GET_PHASING_TSST_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_PHASING_TSST )(( PUINT8 )pSharedInfo + pSharedInfo->ulPhasingTsstListOfst); + +#define mOCT6100_GET_PHASING_TSST_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_PHASING_TSST )(( PUINT8 )pSharedInfo + pSharedInfo->ulPhasingTsstListOfst)) + ulIndex; + +#define mOCT6100_GET_PHASING_TSST_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulPhasingTsstAllocOfst); + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetPhasingTsstSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100ApiPhasingTsstSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100PhasingTsstOpenSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen ); + +UINT32 Oct6100ApiCheckPhasingParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen ); + +UINT32 Oct6100ApiReservePhasingResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen, + OUT PUINT16 f_pusPhasingIndex, + OUT PUINT16 f_pusTsstIndex ); + +UINT32 Oct6100ApiWritePhasingStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen, + IN UINT16 f_usPhasingIndex, + IN UINT16 f_usTsstIndex ); + +UINT32 Oct6100ApiUpdatePhasingEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen, + IN UINT16 f_usPhasingIndex, + IN UINT16 f_usTsstIndex ); + +UINT32 Oct6100PhasingTsstCloseSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PHASING_TSST_CLOSE f_pPhasingTsstClose ); + +UINT32 Oct6100ApiAssertPhasingParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_PHASING_TSST_CLOSE f_pPhasingTsstClose, + OUT PUINT16 f_pusPhasingIndex, + OUT PUINT16 f_pusTsstIndex ); + +UINT32 Oct6100ApiInvalidatePhasingStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsstIndex ); + +UINT32 Oct6100ApiReleasePhasingResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT UINT16 f_usPhasingIndex ); + +UINT32 Oct6100ApiReservePhasingEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusPhasingIndex ); + +UINT32 Oct6100ApiReleasePhasingEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usPhasingIndex ); + +#endif /* #ifndef cOCT6100_REMOVE_PHASING_TSST */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_playout_buf_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_playout_buf_priv.h new file mode 100644 index 0000000..a69e942 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_playout_buf_priv.h @@ -0,0 +1,201 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_playout_buf_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_playout_buf.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_playout_buf_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 22 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_PLAYOUT_BUF_PRIV_H__ +#define __OCT6100_PLAYOUT_BUF_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/* Playout buffer list pointer macros. */ +#define mOCT6100_GET_BUFFER_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_BUFFER )(( PUINT8 )pSharedInfo + pSharedInfo->ulPlayoutBufListOfst ); + +#define mOCT6100_GET_BUFFER_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_BUFFER )(( PUINT8 )pSharedInfo + pSharedInfo->ulPlayoutBufListOfst)) + ulIndex; + +#define mOCT6100_GET_BUFFER_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulPlayoutBufAllocOfst); + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetPlayoutBufferSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100ApiPlayoutBufferSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100BufferLoadSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD f_pBufferLoad, + IN BOOL f_fReserveListStruct, + IN UINT32 f_ulBufIndex ); + +UINT32 Oct6100BufferLoadBlockInitSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD_BLOCK_INIT f_pBufferLoadBlockInit ); + +UINT32 Oct6100BufferLoadBlockSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD_BLOCK f_pBufferLoadBlock ); + +UINT32 Oct6100ApiCheckBufferParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_LOAD f_pBufferLoad, + IN BOOL f_fCheckBufferPtr ); + +UINT32 Oct6100ApiCheckBufferLoadBlockParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_LOAD_BLOCK f_pBufferLoadBlock, + OUT PUINT32 f_pulBufferBase ); + +UINT32 Oct6100ApiReserveBufferResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_LOAD f_pBufferLoad, + IN BOOL f_fReserveListStruct, + IN UINT32 f_ulBufIndex, + OUT PUINT32 f_pulBufIndex, + OUT PUINT32 f_pulBufBase ); + +UINT32 Oct6100ApiWriteBufferInMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulBufferBase, + IN UINT32 f_ulBufferLength, + IN PUINT8 f_pbyBuffer ); + +UINT32 Oct6100ApiUpdateBufferEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD f_pBufferLoad, + IN UINT32 f_ulBufIndex, + IN UINT32 f_ulBufBase ); + +UINT32 Oct6100BufferUnloadSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_UNLOAD f_pBufferUnload, + IN BOOL f_fReleaseListStruct ); + +UINT32 Oct6100ApiAssertBufferParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_UNLOAD f_pBufferUnload, + OUT PUINT32 f_pulBufIndex, + OUT PUINT32 f_pulBufBase ); + +UINT32 Oct6100ApiReleaseBufferResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulBufIndex, + IN UINT32 f_ulBufBase, + IN BOOL f_fReleaseListStruct ); + +UINT32 Oct6100BufferPlayoutAddSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd ); + +UINT32 Oct6100ApiCheckPlayoutAddParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd, + OUT PUINT32 f_pulChannelIndex, + OUT PUINT32 f_pulBufferIndex ); + +UINT32 Oct6100ApiWriteBufferAddStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulBufferIndex ); + +UINT32 Oct6100BufferPlayoutStartSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart, + IN UINT32 f_ulPlayoutStopEventType ); + +UINT32 Oct6100ApiCheckPlayoutStartParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart, + OUT PUINT32 f_pulChannelIndex, + OUT PUINT32 f_pulBufferIndex, + OUT PBOOL f_pfNotifyOnPlayoutStop, + OUT PUINT32 f_pulUserEventId, + OUT PBOOL f_pfAllowStartIfActive ); + +UINT32 Oct6100ApiWriteChanPlayoutStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulBufferIndex, + IN BOOL f_fNotifyOnPlayoutStop, + IN UINT32 f_ulUserEventId, + IN BOOL f_fAllowStartIfActive, + IN UINT32 f_ulPlayoutStopEventType ); + +UINT32 Oct6100ApiUpdateChanPlayoutEntry ( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulBufferIndex ); + +UINT32 Oct6100BufferPlayoutStopSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop ); + +UINT32 Oct6100ApiAssertPlayoutStopParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop, + OUT PUINT32 f_pulChannelIndex, + OUT PUINT16 f_pusEchoMemIndex ); + +UINT32 Oct6100ApiInvalidateChanPlayoutStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop, + IN UINT32 f_ulChannelIndex, + IN UINT16 f_usEchoMemIndex + + ); + +UINT32 Oct6100ApiReleaseChanPlayoutResources ( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop, + IN UINT32 f_ulChannelIndex ); + +UINT32 Oct6100ApiReserveBufPlayoutListEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT32 f_pulBufIndex ); + +UINT32 Oct6100ApiReleaseBufPlayoutListEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulBufIndex ); + +#endif /* __OCT6100_PLAYOUT_BUF_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_remote_debug_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_remote_debug_priv.h new file mode 100644 index 0000000..c599ee9 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_remote_debug_priv.h @@ -0,0 +1,144 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_remote_debug_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_remote_debug.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_remote_debug_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 13 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_REMOTE_DEBUG_PRIV_H__ +#define __OCT6100_REMOTE_DEBUG_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +#define mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, ulIndex, pEntry ) \ + pEntry = ( tPOCT6100_API_REMOTE_DEBUG_SESSION )(( PUINT8 )pSharedInfo + pSharedInfo->RemoteDebugInfo.ulSessionListOfst) + ulIndex; + +#define mOCT6100_GET_REMOTE_DEBUG_TREE_PNT( pSharedInfo, pList ) \ + pList = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->RemoteDebugInfo.ulSessionTreeOfst); + +#define mOCT6100_GET_REMOTE_DEBUG_DATA_BUF_PNT( pSharedInfo, pulDataBuf ) \ + pulDataBuf = ( PUINT16 )(( PUINT8 )pSharedInfo + pSharedInfo->RemoteDebugInfo.ulDataBufOfst); + +#define mOCT6100_GET_REMOTE_DEBUG_SESSION_PKT_CACHE_PNT( pSharedInfo, pulPktCache, ulSessionIndex ) \ + pulPktCache = ( PUINT32 )(( PUINT8 )pSharedInfo + pSharedInfo->RemoteDebugInfo.ulPktCacheOfst) + (ulSessionIndex * (cOCTRPC_MAX_PACKET_BYTE_LENGTH / 4)); + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetRemoteDebugSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100ApiRemoteDebuggingSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiCheckEndianDetectField( + IN tPOCTRPC_OGRDTP_HEADER f_pOgrdtpHeader, + IN UINT32 f_ulPktLengthDword ); + +VOID Oct6100ApiCalculateChecksum( + IN PUINT32 f_pulPktPayload, + IN UINT32 f_ulPktLengthDword, + OUT PUINT32 f_pulChecksum ); + +VOID Oct6100ApiFormResponsePkt( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN PUINT32 f_pulRcvPktPayload, + IN OUT PUINT32 f_pulRspPktPayload, + IN UINT32 f_ulPktLengthDword, + IN BOOL f_fRetryPktResponse, + IN BOOL f_fReplaceProtocolNum, + IN BOOL f_fReplaceInterfaceType, + IN BOOL f_fReplaceInterfaceVersion, + IN UINT32 f_ulSessionIndex, + IN UINT32 f_ulParsingErrorValue, + IN UINT32 f_ulPayloadDwordIndex, + IN UINT32 f_ulChecksum ); + +UINT32 Oct6100ApiCheckPktCommands( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN PUINT32 f_pulRcvPktPayload, + IN OUT PUINT32 f_pulRspPktPayload, + IN UINT32 f_ulSessionIndex, + IN UINT32 f_ulPktLengthDword, + IN UINT32 f_ulChecksum ); + +VOID Oct6100ApiExecutePktCommands( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN PUINT32 f_pulRcvPktPayload, + IN UINT32 f_ulPktLengthDword ); + +UINT32 Oct6100ApiCheckSessionNum( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCTRPC_OGRDTP_HEADER f_pOgrdtpHeader, + OUT PUINT32 f_pulSessionIndex ); + +VOID Oct6100ApiRpcReadWord( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ); + +VOID Oct6100ApiRpcReadBurst( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ); + +VOID Oct6100ApiRpcReadArray( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ); + +VOID Oct6100ApiRpcWriteWord( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ); + +VOID Oct6100ApiRpcWriteSmear( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ); + +VOID Oct6100ApiRpcWriteBurst( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ); + +VOID Oct6100ApiRpcSetHotChannel( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ); + +VOID Oct6100ApiRpcGetDebugChanIndex( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ); + +VOID Oct6100ApiRpcDisconnect( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader, + IN OUT UINT32 f_ulSessionNumber ); + +#endif /* __OCT6100_REMOTE_DEBUG_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tlv_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tlv_priv.h new file mode 100644 index 0000000..e1982bd --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tlv_priv.h @@ -0,0 +1,515 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tlv_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_tlv.c. All elements defined in this + file are for private usage of the API. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 58 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TLV_PRIV_H__ +#define __OCT6100_TLV_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +/* List of TLV types supported by this API. */ +#define cOCT6100_TLV_TYPE_VERSION_NUMBER 0 +#define cOCT6100_TLV_TYPE_CUSTOMER_PROJECT_ID 2 + +#define cOCT6100_TLV_TYPE_POUCH_BASE_ADDRESS 3 +#define cOCT6100_TLV_TYPE_CH0_MAIN_BASE_ADDRESS 4 +#define cOCT6100_TLV_TYPE_CH_MAIN_SIZE 5 +#define cOCT6100_TLV_TYPE_CH_MAIN_IO_OFFSET 6 +#define cOCT6100_TLV_TYPE_CH_MAIN_ZCB_OFFSET 7 +#define cOCT6100_TLV_TYPE_CH_MAIN_ZCB_SIZE 8 +#define cOCT6100_TLV_TYPE_CH_MAIN_XCB_OFFSET 9 +#define cOCT6100_TLV_TYPE_CH_MAIN_XCB_SIZE 10 +#define cOCT6100_TLV_TYPE_CH_MAIN_YCB_OFFSET 11 +#define cOCT6100_TLV_TYPE_CH_MAIN_YCB_SIZE 12 +#define cOCT6100_TLV_TYPE_FREE_MEM_BASE_ADDRESS 13 +#define cOCT6100_TLV_TYPE_CH_ROOT_CONF_OFFSET 14 + +#define cOCT6100_TLV_TYPE_POA_CH_MAIN_ZPO_OFFSET 15 +#define cOCT6100_TLV_TYPE_POA_CH_MAIN_ZPO_SIZE 16 +#define cOCT6100_TLV_TYPE_POA_CH_MAIN_YPO_OFFSET 17 +#define cOCT6100_TLV_TYPE_POA_CH_MAIN_YPO_SIZE 18 +#define cOCT6100_TLV_TYPE_POA_BOFF_RW_ZWP 19 +#define cOCT6100_TLV_TYPE_POA_BOFF_RW_ZIS 20 +#define cOCT6100_TLV_TYPE_POA_BOFF_RW_ZSP 21 +#define cOCT6100_TLV_TYPE_POA_BOFF_RW_YWP 22 +#define cOCT6100_TLV_TYPE_POA_BOFF_RW_YIS 23 +#define cOCT6100_TLV_TYPE_POA_BOFF_RW_YSP 24 +#define cOCT6100_TLV_TYPE_POA_BOFF_RO_ZRP 25 +#define cOCT6100_TLV_TYPE_POA_BOFF_RO_YRP 26 + +#define cOCT6100_TLV_TYPE_CNR_CONF_BOFF_RW_ENABLE 27 +#define cOCT6100_TLV_TYPE_ANR_CONF_BOFF_RW_ENABLE 28 + +#define cOCT6100_TLV_TYPE_HZ_CONF_BOFF_RW_ENABLE 29 +#define cOCT6100_TLV_TYPE_HX_CONF_BOFF_RW_ENABLE 30 + +#define cOCT6100_TLV_TYPE_LCA_Z_CONF_BOFF_RW_GAIN 31 +#define cOCT6100_TLV_TYPE_LCA_Y_CONF_BOFF_RW_GAIN 32 + +#define cOCT6100_TLV_TYPE_CNA_CONF_BOFF_RW_ENABLE 33 + +#define cOCT6100_TLV_TYPE_NOA_CONF_BOFF_RW_ENABLE 34 + +#define cOCT6100_TLV_TYPE_VFA_CONF_BOFF_RW_ENABLE 35 + +#define cOCT6100_TLV_TYPE_TLA_MAIN_IO_BOFF_RW_TAIL_DISP 37 + +#define cOCT6100_TLV_TYPE_STATSA_MAIN_IO_BOFF_RO_EPC 38 +#define cOCT6100_TLV_TYPE_BOOTA_POUCH_BOFF_RW_BOOT_INST 39 +#define cOCT6100_TLV_TYPE_BOOTA_POUCH_BOFF_RW_BOOT_RESULT 40 + +#define cOCT6100_TLV_TYPE_DIS_CONF_BOFF_RW_ENABLE 41 +#define cOCT6100_TLV_TYPE_TDM_CONF_BOFF_RW_ENABLE 42 +#define cOCT6100_TLV_TYPE_NT_CONF_BOFF_RW_ENABLE 43 +#define cOCT6100_TLV_TYPE_AEC_CONF_BOFF_RW_ENABLE 44 + +#define cOCT6100_TLV_TYPE_PCM_LEAK_CONF_BOFF_RW 45 +#define cOCT6100_TLV_TYPE_DEFAULT_ERL_CONF_BOFF_RW 46 +#define cOCT6100_TLV_TYPE_TONE_REM_CONF_BOFF_RW_ENABLE 47 + +#define cOCT6100_TLV_TYPE_TLA_MAIN_IO_BOFF_RW_MAX_ECHO_POINT 48 + +#define cOCT6100_TLV_TYPE_NLP_CONV_CAP_CONF_BOFF_RW 49 +#define cOCT6100_TLV_TYPE_MATRIX_EVENT_SIZE 50 +#define cOCT6100_TLV_TYPE_CNR_RW_ENABLE 51 +#define cOCT6100_TLV_TYPE_MAX_TAIL_LENGTH_RW_ENABLE 52 + +#define cOCT6100_TLV_TYPE_PLAYOUT_ENABLE 53 +#define cOCT6100_TLV_TYPE_DOMINANT_SPEAKER_BOFF_RW_ENABLE 54 + +#define cOCT6100_TLV_TYPE_ANR_RW_ENABLE 57 +#define cOCT6100_TLV_TYPE_TONE_REMOVAL_ENABLE 58 +#define cOCT6100_TLV_TYPE_MUSIC_PROTECTION_RW_ENABLE 59 +#define cOCT6100_TLV_TYPE_TAIL_DISP_CONF_BOFF_RW_ENABLE 60 +#define cOCT6100_TLV_TYPE_IDLE_CODE_DETECTION_ENABLE 62 + +#define cOCT6100_TLV_TYPE_AEC_DEFAULT_ERL_BOFF 64 + +#define cOCT6100_TLV_TYPE_Z_ALC_TARGET_BOFF 65 +#define cOCT6100_TLV_TYPE_Y_ALC_TARGET_BOFF 66 +#define cOCT6100_TLV_TYPE_Z_HLC_TARGET_BOFF 67 +#define cOCT6100_TLV_TYPE_Y_HLC_TARGET_BOFF 68 +#define cOCT6100_TLV_TYPE_ALC_HLC_STATUS_BOFF 69 + +#define cOCT6100_TLV_TYPE_Z_PLAYOUT_HARD_SKIP_BOFF 70 +#define cOCT6100_TLV_TYPE_Y_PLAYOUT_HARD_SKIP_BOFF 71 + +#define cOCT6100_TLV_TYPE_AFT_FIELD_BOFF 72 + +#define cOCT6100_TLV_TYPE_VOICE_DETECTED_STAT_BOFF 73 + +#define cOCT6100_TLV_TYPE_GAIN_APPLIED_RIN_STAT_BOFF 74 +#define cOCT6100_TLV_TYPE_GAIN_APPLIED_SOUT_STAT_BOFF 75 + +#define cOCT6100_TLV_TYPE_MAX_ADAPT_ALE_BOFF 77 +#define cOCT6100_TLV_TYPE_RIN_ANR_BOFF 78 + +#define cOCT6100_TLV_TYPE_NUMBER_PLAYOUT_EVENTS 79 + +#define cOCT6100_TLV_TYPE_RIN_MUTE_BOFF 80 +#define cOCT6100_TLV_TYPE_SIN_MUTE_BOFF 81 + +#define cOCT6100_TLV_TYPE_CHAN_TAIL_LENGTH_BOFF 82 + +#define cOCT6100_TLV_TYPE_CHAN_VQE_TONE_DISABLING_BOFF 83 + +#define cOCT6100_TLV_TYPE_ANR_SNR_IMPROVEMENT_BOFF 84 +#define cOCT6100_TLV_TYPE_ANR_AGRESSIVITY_BOFF 85 + +#define cOCT6100_TLV_TYPE_RIN_TONE_REM_CONF_BOFF_RW_ENABLE 86 +#define cOCT6100_TLV_TYPE_RIN_TONE_REM_COUNTER_BOFF 87 + +#define cOCT6100_TLV_TYPE_AF_TAIL_DISP_VALUE_BOFF 88 + +#define cOCT6100_TLV_TYPE_POUCH_COUNTER_BOFF 89 + +#define cOCT6100_TLV_TYPE_AEC_TAIL_LENGTH_BOFF 90 + +#define cOCT6100_TLV_TYPE_MATRIX_DWORD_BASE 91 +#define cOCT6100_TLV_TYPE_DEBUG_CHAN_STATS_BYTE_SIZE 92 +#define cOCT6100_TLV_TYPE_RECORDED_PCM_EVENT_BYTE_SIZE 93 +#define cOCT6100_TLV_TYPE_HOT_CHANNEL_SELECT_DWORD_BASE 94 +#define cOCT6100_TLV_TYPE_IS_ISR_CALLED_BOFF 95 + +#define cOCT6100_TLV_TYPE_MATRIX_TIMESTAMP_DWORD_BASE 96 + +#define cOCT6100_TLV_TYPE_CHAN_MAIN_IO_STATS_OFFSET 100 +#define cOCT6100_TLV_TYPE_CHAN_MAIN_IO_STATS_SIZE 101 + +#define cOCT6100_TLV_TYPE_AF_WRITE_PTR_BYTE_OFFSET 104 +#define cOCT6100_TLV_TYPE_MATRIX_WP_DWORD_BASE 105 +#define cOCT6100_TLV_TYPE_DEBUG_CHAN_LITE_STATS_BYTE_SIZE 106 + +#define cOCT6100_TLV_TYPE_MUSIC_PROTECTION_ENABLE_BOFF 107 + +#define cOCT6100_TLV_TYPE_IMAGE_TYPE 108 +#define cOCT6100_TLV_TYPE_MAX_WIRELINE_CHANNELS 111 + +#define cOCT6100_TLV_TYPE_AF_EVENT_CB_SIZE 112 + +#define cOCT6100_TLV_TYPE_ZZ_ENERGY_CHAN_STATS_BOFF 116 +#define cOCT6100_TLV_TYPE_YY_ENERGY_CHAN_STATS_BOFF 117 + +#define cOCT6100_TLV_TYPE_BUFFER_PLAYOUT_SKIP_IN_EVENTS 119 + +#define cOCT6100_TLV_TYPE_SOUT_NOISE_BLEACHING 121 + +#define cOCT6100_TLV_TYPE_DOUBLE_TALK_BEH_MODE 124 +#define cOCT6100_TLV_TYPE_DOUBLE_TALK_BEH_MODE_BOFF 125 + +#define cOCT6100_TLV_TYPE_IDLE_CODE_DETECTION_BOFF 136 + +#define cOCT6100_TLV_TYPE_NLP_STATISTICS 138 + +#define cOCT6100_TLV_TYPE_RIN_ANR_VALUE 147 + +#define cOCT6100_TLV_TYPE_ADPCM_ENABLE 150 +#define cOCT6100_TLV_TYPE_NUM_TONE_DETECTOR 151 +#define cOCT6100_TLV_TYPE_CONFERENCING_ENABLE 152 +#define cOCT6100_TLV_TYPE_MAX_NUMBER_OF_CHANNELS 153 +#define cOCT6100_TLV_TYPE_DEBUG_CHAN_INDEX_VALUE 154 +#define cOCT6100_TLV_TYPE_TONE_DETECTOR_PROFILE 155 +#define cOCT6100_TLV_TYPE_TEST_MODE_ENABLE 156 +#define cOCT6100_TLV_TYPE_MAX_TAIL_DISPLACEMENT 157 + + +/* TLV length defines. */ +#define cOCT6100_TLV_MIN_LENGTH_DEFAULT 4 +#define cOCT6100_TLV_MAX_LENGTH_DEFAULT 0xFFFFFFFF + +#define cOCT6100_TLV_MIN_LENGTH_VERSION_NUMBER 4 +#define cOCT6100_TLV_MAX_LENGTH_VERSION_NUMBER 1016 +#define cOCT6100_TLV_MIN_LENGTH_CUSTOMER_PROJECT_ID 4 +#define cOCT6100_TLV_MAX_LENGTH_CUSTOMER_PROJECT_ID 4 + + +#define cOCT6100_TLV_MIN_LENGTH_CH0_MAIN_BASE_ADDRESS 4 +#define cOCT6100_TLV_MAX_LENGTH_CH0_MAIN_BASE_ADDRESS 4 +#define cOCT6100_TLV_MIN_LENGTH_CH_MAIN_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_CH_MAIN_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_CH_MAIN_IO_OFFSET 4 +#define cOCT6100_TLV_MAX_LENGTH_CH_MAIN_IO_OFFSET 4 +#define cOCT6100_TLV_MIN_LENGTH_CH_MAIN_ZCB_OFFSET 4 +#define cOCT6100_TLV_MAX_LENGTH_CH_MAIN_ZCB_OFFSET 4 +#define cOCT6100_TLV_MIN_LENGTH_CH_MAIN_ZCB_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_CH_MAIN_ZCB_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_CH_MAIN_XCB_OFFSET 4 +#define cOCT6100_TLV_MAX_LENGTH_CH_MAIN_XCB_OFFSET 4 +#define cOCT6100_TLV_MIN_LENGTH_CH_MAIN_XCB_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_CH_MAIN_XCB_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_CH_MAIN_YCB_OFFSET 4 +#define cOCT6100_TLV_MAX_LENGTH_CH_MAIN_YCB_OFFSET 4 +#define cOCT6100_TLV_MIN_LENGTH_CH_MAIN_YCB_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_CH_MAIN_YCB_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_FREE_MEM_BASE_ADDRESS 4 +#define cOCT6100_TLV_MAX_LENGTH_FREE_MEM_BASE_ADDRESS 4 +#define cOCT6100_TLV_MIN_LENGTH_CH_ROOT_CONF_OFFSET 4 +#define cOCT6100_TLV_MAX_LENGTH_CH_ROOT_CONF_OFFSET 4 + +#define cOCT6100_TLV_MIN_LENGTH_POA_CH_MAIN_ZPO_OFFSET 4 +#define cOCT6100_TLV_MAX_LENGTH_POA_CH_MAIN_ZPO_OFFSET 4 +#define cOCT6100_TLV_MIN_LENGTH_POA_CH_MAIN_ZPO_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_POA_CH_MAIN_ZPO_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_POA_CH_MAIN_YPO_OFFSET 4 +#define cOCT6100_TLV_MAX_LENGTH_POA_CH_MAIN_YPO_OFFSET 4 +#define cOCT6100_TLV_MIN_LENGTH_POA_CH_MAIN_YPO_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_POA_CH_MAIN_YPO_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_ZWP 8 +#define cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_ZWP 8 +#define cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_ZIS 8 +#define cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_ZIS 8 +#define cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_ZSP 8 +#define cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_ZSP 8 +#define cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_YWP 8 +#define cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_YWP 8 +#define cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_YIS 8 +#define cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_YIS 8 +#define cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_YSP 8 +#define cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_YSP 8 +#define cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RO_ZRP 8 +#define cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RO_ZRP 8 +#define cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RO_YRP 8 +#define cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RO_YRP 8 + +#define cOCT6100_TLV_MIN_LENGTH_CNR_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_CNR_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_ANR_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_ANR_CONF_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_HZ_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_HZ_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_HX_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_HX_CONF_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_LCA_Z_CONF_BOFF_RW_GAIN 8 +#define cOCT6100_TLV_MAX_LENGTH_LCA_Z_CONF_BOFF_RW_GAIN 8 +#define cOCT6100_TLV_MIN_LENGTH_LCA_Y_CONF_BOFF_RW_GAIN 8 +#define cOCT6100_TLV_MAX_LENGTH_LCA_Y_CONF_BOFF_RW_GAIN 8 + +#define cOCT6100_TLV_MIN_LENGTH_CNA_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_CNA_CONF_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_NOA_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_NOA_CONF_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_VFA_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_VFA_CONF_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_TLA_MAIN_IO_BOFF_RW_TAIL_DISP 8 +#define cOCT6100_TLV_MAX_LENGTH_TLA_MAIN_IO_BOFF_RW_TAIL_DISP 8 + +#define cOCT6100_TLV_MIN_LENGTH_STATSA_MAIN_IO_BOFF_RO_EPC 8 +#define cOCT6100_TLV_MAX_LENGTH_STATSA_MAIN_IO_BOFF_RO_EPC 8 + +#define cOCT6100_TLV_MIN_LENGTH_BOOTA_POUCH_BOFF_RW_BOOT_INST 8 +#define cOCT6100_TLV_MAX_LENGTH_BOOTA_POUCH_BOFF_RW_BOOT_INST 8 +#define cOCT6100_TLV_MIN_LENGTH_BOOTA_POUCH_BOFF_RW_BOOT_RESULT 8 +#define cOCT6100_TLV_MAX_LENGTH_BOOTA_POUCH_BOFF_RW_BOOT_RESULT 8 + +#define cOCT6100_TLV_MIN_LENGTH_CHAN_MAIN_IO_STATS_OFFSET 4 +#define cOCT6100_TLV_MAX_LENGTH_CHAN_MAIN_IO_STATS_OFFSET 4 +#define cOCT6100_TLV_MIN_LENGTH_CHAN_MAIN_IO_STATS_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_CHAN_MAIN_IO_STATS_SIZE 4 + +#define cOCT6100_TLV_MIN_LENGTH_CDA_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_CDA_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_TDM_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_TDM_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_DIS_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_DIS_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_NT_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_NT_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_AEC_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_AEC_CONF_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_PCM_LEAK_CONF_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_PCM_LEAK_CONF_BOFF_RW 8 +#define cOCT6100_TLV_MIN_LENGTH_DEFAULT_ERL_CONF_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_DEFAULT_ERL_CONF_BOFF_RW 8 +#define cOCT6100_TLV_MIN_LENGTH_TONE_REM_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_TONE_REM_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_NLP_CONV_CAP_CONF_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_NLP_CONV_CAP_CONF_BOFF_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_TLA_MAIN_IO_BOFF_RW_MAX_ECHO_POINT 8 +#define cOCT6100_TLV_MAX_LENGTH_TLA_MAIN_IO_BOFF_RW_MAX_ECHO_POINT 8 + +#define cOCT6100_TLV_MIN_LENGTH_DOMINANT_SPEAKER_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_DOMINANT_SPEAKER_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_TAIL_DISP_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_TAIL_DISP_CONF_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_AEC_DEFAULT_ERL_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_AEC_DEFAULT_ERL_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_Z_ALC_TARGET_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_Z_ALC_TARGET_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_Y_ALC_TARGET_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_Y_ALC_TARGET_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_Z_HLC_TARGET_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_Z_HLC_TARGET_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_Y_HLC_TARGET_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_Y_HLC_TARGET_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_ALC_HLC_STATUS_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_ALC_HLC_STATUS_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_Z_PLAYOUT_HARD_SKIP_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_Z_PLAYOUT_HARD_SKIP_BOFF_RW 8 +#define cOCT6100_TLV_MIN_LENGTH_Y_PLAYOUT_HARD_SKIP_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_Y_PLAYOUT_HARD_SKIP_BOFF_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_AFT_FIELD_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_AFT_FIELD_BOFF_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_VOICE_DETECTED_STAT_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_VOICE_DETECTED_STAT_BOFF_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_GAIN_APPLIED_RIN_STAT_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_GAIN_APPLIED_RIN_STAT_BOFF_RW 8 +#define cOCT6100_TLV_MIN_LENGTH_GAIN_APPLIED_SOUT_STAT_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_GAIN_APPLIED_SOUT_STAT_BOFF_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_MAX_ADAPT_ALE_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_MAX_ADAPT_ALE_BOFF_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_RIN_ANR_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_RIN_ANR_BOFF_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_RIN_ANR_VALUE_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_RIN_ANR_VALUE_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_RIN_MUTE_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_RIN_MUTE_BOFF_RW 8 +#define cOCT6100_TLV_MIN_LENGTH_SIN_MUTE_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_SIN_MUTE_BOFF_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_ANR_SNR_IMPROVEMENT_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_ANR_SNR_IMPROVEMENT_BOFF_RW 8 +#define cOCT6100_TLV_MIN_LENGTH_ANR_AGRESSIVITY_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_ANR_AGRESSIVITY_BOFF_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_CHAN_TAIL_LENGTH_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_CHAN_TAIL_LENGTH_BOFF 8 + +#define cOCT6100_TLV_MIN_LENGTH_CHAN_VQE_TONE_DIS_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_CHAN_VQE_TONE_DIS_BOFF 8 + +#define cOCT6100_TLV_MIN_LENGTH_RIN_TONE_REM_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_RIN_TONE_REM_CONF_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_RIN_TONE_REM_COUNTER_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_RIN_TONE_REM_COUNTER_BOFF_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_AF_TAIL_DISP_VALUE_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_AF_TAIL_DISP_VALUE_BOFF 8 + +#define cOCT6100_TLV_MIN_LENGTH_POUCH_COUNTER_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_POUCH_COUNTER_BOFF 8 + +#define cOCT6100_TLV_MIN_LENGTH_AEC_TAIL_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_AEC_TAIL_BOFF 8 + +#define cOCT6100_TLV_MIN_LENGTH_IS_ISR_CALLED_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_IS_ISR_CALLED_BOFF 8 + +#define cOCT6100_TLV_MIN_LENGTH_MUSIC_PROTECTION_ENABLE_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_MUSIC_PROTECTION_ENABLE_BOFF 8 + +#define cOCT6100_TLV_MIN_LENGTH_ZZ_ENERGY_CHAN_STATS_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_ZZ_ENERGY_CHAN_STATS_BOFF 8 +#define cOCT6100_TLV_MIN_LENGTH_YY_ENERGY_CHAN_STATS_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_YY_ENERGY_CHAN_STATS_BOFF 8 + +#define cOCT6100_TLV_MIN_LENGTH_DOUBLE_TALK_BEH_MODE_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_DOUBLE_TALK_BEH_MODE_BOFF 8 + +#define cOCT6100_TLV_MIN_LENGTH_IDLE_CODE_DETECTION_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_IDLE_CODE_DETECTION_BOFF 8 + +#define cOCT6100_TLV_MIN_LENGTH_DEBUG_CHAN_INDEX_VALUE 4 +#define cOCT6100_TLV_MAX_LENGTH_DEBUG_CHAN_INDEX_VALUE 4 +#define cOCT6100_TLV_MIN_LENGTH_ADPCM_ENABLE 4 +#define cOCT6100_TLV_MAX_LENGTH_ADPCM_ENABLE 4 +#define cOCT6100_TLV_MIN_LENGTH_NUM_TONE_DETECTOR 4 +#define cOCT6100_TLV_MAX_LENGTH_NUM_TONE_DETECTOR 4 +#define cOCT6100_TLV_MIN_LENGTH_CONFERENCING_ENABLE 4 +#define cOCT6100_TLV_MAX_LENGTH_CONFERENCING_ENABLE 4 +#define cOCT6100_TLV_MIN_LENGTH_MAX_NUMBER_OF_CHANNELS 4 +#define cOCT6100_TLV_MAX_LENGTH_MAX_NUMBER_OF_CHANNELS 4 +#define cOCT6100_TLV_MIN_LENGTH_TONE_DETECTOR_PROFILE 4 +#define cOCT6100_TLV_MAX_LENGTH_TONE_DETECTOR_PROFILE 4 +#define cOCT6100_TLV_MIN_LENGTH_TEST_MODE_ENABLE 4 +#define cOCT6100_TLV_MAX_LENGTH_TEST_MODE_ENABLE 4 +#define cOCT6100_TLV_MIN_LENGTH_MAX_TAIL_DISPLACEMENT 4 +#define cOCT6100_TLV_MAX_LENGTH_MAX_TAIL_DISPLACEMENT 4 +#define cOCT6100_TLV_MIN_LENGTH_MATRIX_EVENT_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_MATRIX_EVENT_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_CNR_RW_ENABLE 4 +#define cOCT6100_TLV_MAX_LENGTH_CNR_RW_ENABLE 4 +#define cOCT6100_TLV_MIN_LENGTH_ANR_RW_ENABLE 4 +#define cOCT6100_TLV_MAX_LENGTH_ANR_RW_ENABLE 4 +#define cOCT6100_TLV_MIN_LENGTH_MAX_TAIL_LENGTH_RW_ENABLE 4 +#define cOCT6100_TLV_MAX_LENGTH_MAX_TAIL_LENGTH_RW_ENABLE 4 +#define cOCT6100_TLV_MIN_LENGTH_PLAYOUT_ENABLE 4 +#define cOCT6100_TLV_MAX_LENGTH_PLAYOUT_ENABLE 4 +#define cOCT6100_TLV_MIN_LENGTH_MUSIC_PROTECTION_RW_ENABLE 4 +#define cOCT6100_TLV_MAX_LENGTH_MUSIC_PROTECTION_RW_ENABLE 4 +#define cOCT6100_TLV_MIN_LENGTH_TONE_REMOVAL_ENABLE 4 +#define cOCT6100_TLV_MAX_LENGTH_TONE_REMOVAL_ENABLE 4 +#define cOCT6100_TLV_MIN_LENGTH_NUMBER_PLAYOUT_EVENTS 4 +#define cOCT6100_TLV_MAX_LENGTH_NUMBER_PLAYOUT_EVENTS 4 +#define cOCT6100_TLV_MIN_LENGTH_MATRIX_DWORD_BASE 4 +#define cOCT6100_TLV_MAX_LENGTH_MATRIX_DWORD_BASE 4 +#define cOCT6100_TLV_MIN_LENGTH_DEBUG_CHAN_STATS_BYTE_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_DEBUG_CHAN_STATS_BYTE_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_HOT_CHANNEL_SELECT_DWORD_BASE 4 +#define cOCT6100_TLV_MAX_LENGTH_HOT_CHANNEL_SELECT_DWORD_BASE 4 +#define cOCT6100_TLV_MIN_LENGTH_TIMESTAMP_DWORD_BASE 4 +#define cOCT6100_TLV_MAX_LENGTH_TIMESTAMP_DWORD_BASE 4 +#define cOCT6100_TLV_MIN_LENGTH_AF_WRITE_PTR_BYTE_OFFSET 4 +#define cOCT6100_TLV_MAX_LENGTH_AF_WRITE_PTR_BYTE_OFFSET 4 +#define cOCT6100_TLV_MIN_LENGTH_RECORDED_PCM_EVENT_BYTE_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_RECORDED_PCM_EVENT_BYTE_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_MATRIX_WP_DWORD_BASE 4 +#define cOCT6100_TLV_MAX_LENGTH_MATRIX_WP_DWORD_BASE 4 +#define cOCT6100_TLV_MIN_LENGTH_DEBUG_CHAN_LITE_STATS_BYTE_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_DEBUG_CHAN_LITE_STATS_BYTE_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_IMAGE_TYPE 4 +#define cOCT6100_TLV_MAX_LENGTH_IMAGE_TYPE 4 +#define cOCT6100_TLV_MIN_LENGTH_MAX_WIRELINE_CHANNELS 4 +#define cOCT6100_TLV_MAX_LENGTH_MAX_WIRELINE_CHANNELS 4 +#define cOCT6100_TLV_MIN_LENGTH_AF_EVENT_CB_BYTE_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_AF_EVENT_CB_BYTE_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_BUFFER_PLAYOUT_SKIP_IN_EVENTS 4 +#define cOCT6100_TLV_MAX_LENGTH_BUFFER_PLAYOUT_SKIP_IN_EVENTS 4 +#define cOCT6100_TLV_MIN_LENGTH_DOUBLE_TALK_BEH_MODE 4 +#define cOCT6100_TLV_MAX_LENGTH_DOUBLE_TALK_BEH_MODE 4 +#define cOCT6100_TLV_MIN_LENGTH_SOUT_NOISE_BLEACHING 4 +#define cOCT6100_TLV_MAX_LENGTH_SOUT_NOISE_BLEACHING 4 +#define cOCT6100_TLV_MIN_LENGTH_IDLE_CODE_DETECTION 4 +#define cOCT6100_TLV_MAX_LENGTH_IDLE_CODE_DETECTION 4 +#define cOCT6100_TLV_MIN_LENGTH_NLP_STATISTICS 4 +#define cOCT6100_TLV_MAX_LENGTH_NLP_STATISTICS 4 + + +/***************************** TYPES ***************************************/ + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiProcessTlvRegion( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiInterpretTlvEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulTlvFieldType, + IN UINT32 f_ulTlvFieldLength, + IN UINT32 f_ulTlvValueAddress ); + +UINT32 Oct6100ApiTlvCheckLengthField( + IN OUT UINT32 f_ulTlvFieldLength, + IN UINT32 f_ulMinLengthValue, + IN UINT32 f_ulMaxLengthValue ); + +UINT32 Oct6100ApiTlvReadDword( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulAddress, + OUT PUINT32 f_pulReadData ); + +UINT32 Oct6100ApiTlvReadBitOffsetStruct( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulAddress, + OUT tPOCT6100_TLV_OFFSET f_pBitOffsetStruct ); + +#endif /* __OCT6100_TLV_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tone_detection_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tone_detection_priv.h new file mode 100644 index 0000000..c3192c2 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tone_detection_priv.h @@ -0,0 +1,111 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tone_detection_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_tone_detection.c. All elements defined in + this file are for private usage of the API. All public elements are + defined in the oct6100_tone_detection_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 14 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TONE_DETECTION_PRIV_H__ +#define __OCT6100_TONE_DETECTION_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ToneDetectionEnableSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TONE_DETECTION_ENABLE f_pToneDetectEnable ); + +UINT32 Oct6100ApiCheckToneEnableParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TONE_DETECTION_ENABLE f_pToneDetectEnable, + OUT PUINT32 f_pulChannelIndex, + OUT PUINT32 f_pulToneEventNumber, + + OUT PUINT32 f_pulExtToneChanIndex ); + +UINT32 Oct6100ApiWriteToneDetectEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulToneEventNumber, + + IN UINT32 f_ulExtToneChanIndex ); + +UINT32 Oct6100ApiUpdateChanToneDetectEntry ( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulToneEventNumber, + IN UINT32 f_ulExtToneChanIndex ); + +UINT32 Oct6100ToneDetectionDisableSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TONE_DETECTION_DISABLE f_pToneDetectDisable ); + +UINT32 Oct6100ApiAssertToneDetectionParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TONE_DETECTION_DISABLE f_pToneDetectDisable, + OUT PUINT32 f_pulChannelIndex, + OUT PUINT32 f_pulToneEventNumber, + OUT PUINT32 f_pulExtToneChanIndex, + + OUT PBOOL f_pfDisableAll ); + +UINT32 Oct6100ApiClearToneDetectionEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulToneEventNumber, + IN UINT32 f_ulExtToneChanIndex, + + IN BOOL f_fDisableAll ); + +UINT32 Oct6100ApiReleaseToneDetectionEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulToneEventNumber, + IN UINT32 f_ulExtToneChanIndex, + IN BOOL f_fDisableAll ); + +UINT32 Oct6100ApiIsSSTone( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulToneEventNumber, + OUT PBOOL f_fSSTone ); + +UINT32 Oct6100ApiIs2100Tone( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulToneEventNumber, + OUT PBOOL f_fIs2100Tone ); + +#endif /* __OCT6100_TONE_DETECTION_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tsi_cnct_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tsi_cnct_priv.h new file mode 100644 index 0000000..b7c57f3 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tsi_cnct_priv.h @@ -0,0 +1,126 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tsi_cnct_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_tsi_cnct.c. All elements defined in + this file are for private usage of the API. All public elements are + defined in the oct6100_tsi_cnct_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 14 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TSI_CNCT_PRIV_H__ +#define __OCT6100_TSI_CNCT_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/* TSI connection list pointer macros. */ +#define mOCT6100_GET_TSI_CNCT_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_TSI_CNCT )(( PUINT8 )pSharedInfo + pSharedInfo->ulTsiCnctListOfst ); + +#define mOCT6100_GET_TSI_CNCT_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_TSI_CNCT )(( PUINT8 )pSharedInfo + pSharedInfo->ulTsiCnctListOfst)) + ulIndex; + +#define mOCT6100_GET_TSI_CNCT_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulTsiCnctAllocOfst); + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetTsiCnctSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100ApiTsiCnctSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + + +UINT32 Oct6100TsiCnctOpenSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen ); + +UINT32 Oct6100ApiCheckTsiParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen ); + +UINT32 Oct6100ApiReserveTsiResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen, + OUT PUINT16 f_pusTsiChanIndex, + OUT PUINT16 f_pusTsiMemIndex, + OUT PUINT16 f_pusInputTsstIndex, + OUT PUINT16 f_pusOutputTsstIndex ); + +UINT32 Oct6100ApiWriteTsiStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen, + IN UINT16 f_usTsiMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ); + +UINT32 Oct6100ApiUpdateTsiEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen, + IN UINT16 f_usTsiChanIndex, + IN UINT16 f_usTsiMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ); + + +UINT32 Oct6100TsiCnctCloseSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TSI_CNCT_CLOSE f_pTsiCnctClose ); + +UINT32 Oct6100ApiAssertTsiParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TSI_CNCT_CLOSE f_pTsiCnctClose, + OUT PUINT16 f_pusTsiChanIndex, + OUT PUINT16 f_pusTsiMemIndex, + OUT PUINT16 f_pusInputTsstIndex, + OUT PUINT16 f_pusOutputTsstIndex ); + +UINT32 Oct6100ApiInvalidateTsiStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ); + +UINT32 Oct6100ApiReleaseTsiResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsiChanIndex, + IN UINT16 f_usTsiMemIndex ); + +UINT32 Oct6100ApiReserveTsiCnctEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusTsiChanIndex ); + +UINT32 Oct6100ApiReleaseTsiCnctEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsiChanIndex ); + +#endif /* __OCT6100_TSI_CNCT_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tsst_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tsst_priv.h new file mode 100644 index 0000000..ca080b3 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tsst_priv.h @@ -0,0 +1,89 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tsst_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_tsst.c. All elements defined in + this file are for private usage of the API. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 14 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TSST_PRIV_H__ +#define __OCT6100_TSST_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +/* TSST allocation and serialization pointer macros. */ +#define mOCT6100_GET_TSST_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PUINT32 )(( PUINT8 )pSharedInfo + pSharedInfo->ulTsstAllocOfst); + +#define mOCT6100_GET_TSST_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_TSST_ENTRY )(( PUINT8 )pSharedInfo + pSharedInfo->ulTsstListOfst ); + +#define mOCT6100_GET_TSST_LIST_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_TSST_ENTRY )(( PUINT8 )pSharedInfo + pSharedInfo->ulTsstListOfst)) + ulIndex; + +#define mOCT6100_GET_TSST_LIST_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulTsstListAllocOfst); + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetTsstSwSizes( + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100ApiTsstSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiValidateTsst( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulNumTssts, + IN UINT32 f_ulTimeslot, + IN UINT32 f_ulStream, + IN UINT32 f_ulDirection ); + +UINT32 Oct6100ApiReserveTsst( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulTimeslot, + IN UINT32 f_ulStream, + IN UINT32 f_ulNumTsst, + IN UINT32 f_ulDirection, + OUT PUINT16 f_pusTsstMemIndex, + OUT PUINT16 f_pusTsstListIndex ); + +UINT32 Oct6100ApiReleaseTsst( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulTimeslot, + IN UINT32 f_ulStream, + IN UINT32 f_ulNumTsst, + IN UINT32 f_ulDirection, + IN UINT16 f_usTsstListIndex ); + +#endif /* __OCT6100_TSST_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_version.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_version.h new file mode 100644 index 0000000..7b3eb5d --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_version.h @@ -0,0 +1,39 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_version.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the version of API. To obtain that version + number, the user must call the API function Oct6100ApiGetVersion(). + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 52 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_VERSION_H__ +#define __OCT6100_VERSION_H__ + +/* String version of the OCT6100 API.*/ + +#define cOCT6100_API_VERSION "OCT6100API-01.00-PR49" + +#endif /* __OCT6100_VERSION_H__ */ diff --git a/xpp/oct612x/test.c b/xpp/oct612x/test.c new file mode 100644 index 0000000..0105e58 --- /dev/null +++ b/xpp/oct612x/test.c @@ -0,0 +1,46 @@ +/* + NOTE: This is not intended to be a functional program. Its only purpose + is to act as a tool to find out what portions of the Octasic API kit we + actually need to link into our drivers. As such, it references every API + call that the actual drivers use, and we let the compiler and linker tell + us what parts of each API module are actually needed to successfully + build this program. + */ +#include "oct6100api/oct6100_api.h" + +int main(int argc, char **argv) +{ + tPOCT6100_INSTANCE_API pApiInstance; + UINT32 ulResult; + tOCT6100_CHANNEL_MODIFY modify; + tOCT6100_INTERRUPT_FLAGS InterruptFlags; + tOCT6100_TONE_EVENT tonefound; + tOCT6100_EVENT_GET_TONE tonesearch; + tOCT6100_CHIP_OPEN ChipOpen; + tOCT6100_GET_INSTANCE_SIZE InstanceSize; + tOCT6100_CHANNEL_OPEN ChannelOpen; + tOCT6100_TONE_DETECTION_ENABLE enable; + tOCT6100_CHIP_CLOSE ChipClose; + tOCT6100_API_GET_CAPACITY_PINS CapacityPins; + + Oct6100ChannelModifyDef(&modify); + ulResult = Oct6100ChannelModify(pApiInstance, &modify); + Oct6100InterruptServiceRoutineDef(&InterruptFlags); + Oct6100InterruptServiceRoutine(pApiInstance, &InterruptFlags); + Oct6100EventGetToneDef(&tonesearch); + ulResult = Oct6100EventGetTone(pApiInstance, &tonesearch); + Oct6100ChipOpenDef(&ChipOpen); + Oct6100GetInstanceSizeDef(&InstanceSize); + ulResult = Oct6100GetInstanceSize(&ChipOpen, &InstanceSize); + ulResult = Oct6100ChipOpen(pApiInstance, &ChipOpen); + Oct6100ChannelOpenDef(&ChannelOpen); + ulResult = Oct6100ChannelOpen(pApiInstance, &ChannelOpen); + Oct6100ToneDetectionEnableDef(&enable); + Oct6100ToneDetectionEnable(pApiInstance, &enable); + Oct6100ChipCloseDef(&ChipClose); + ulResult = Oct6100ChipClose(pApiInstance, &ChipClose); + Oct6100ApiGetCapacityPinsDef(&CapacityPins); + ulResult = Oct6100ApiGetCapacityPins(&CapacityPins); + + return 0; +} diff --git a/xpp/parse_span_specs.c b/xpp/parse_span_specs.c new file mode 100644 index 0000000..4cbc27f --- /dev/null +++ b/xpp/parse_span_specs.c @@ -0,0 +1,152 @@ +/* + * Written by Oron Peled + * Copyright (C) 2014, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "parse_span_specs.h" + +void free_span_specifications(struct span_specs *span_specs) +{ + if (span_specs) { + if (span_specs->buf) + free(span_specs->buf); + free(span_specs); + } +} + +static enum tdm_codec is_alaw_span_type(const char *span_type) +{ + assert(span_type); + if (strcmp(span_type, "E1") == 0) + return TDM_CODEC_ALAW; + else if (strcmp(span_type, "T1") == 0) + return TDM_CODEC_ULAW; + return TDM_CODEC_UNKNOWN; +} + +struct span_specs *parse_span_specifications(const char *spec_string, int default_is_alaw) +{ + struct span_specs *span_specs; + char *p; + int spanno; + int i; + + if (!spec_string) + return NULL; + /* Allocate and Initialize */ + span_specs = calloc(sizeof(char *), MAX_SPANNO); + if (!span_specs) + goto err; + for (spanno = 0; spanno < MAX_SPANNO; spanno++) + span_specs->span_is_alaw[spanno] = TDM_CODEC_UNKNOWN; + span_specs->buf = strdup(spec_string); + if (!span_specs->buf) + goto err; + for (i = 0;; i++) { + char *curr_item; + char *tokenize_key; + char *key; + char *value; + enum tdm_codec is_alaw; + int matched; + + /* Split to items */ + p = (i == 0) ? span_specs->buf : NULL; + p = strtok_r(p, " \t,", &curr_item); + if (!p) + break; + + /* Split to : */ + key = strtok_r(p, ":", &tokenize_key); + if (!key) { + fprintf(stderr, + "Missing ':' (item #%d inside '%s')\n", + i+1, spec_string); + goto err; + } + value = strtok_r(NULL, ":", &tokenize_key); + if (!value) { + fprintf(stderr, + "Missing value after ':' (item #%d inside '%s')\n", + i+1, spec_string); + goto err; + } + + /* Match span specification and set alaw/ulaw */ + is_alaw = is_alaw_span_type(value); + if (is_alaw == TDM_CODEC_UNKNOWN) { + fprintf(stderr, + "Illegal span type '%s' (item #%d inside '%s')\n", + value, i+1, spec_string); + goto err; + } + matched = 0; + for (spanno = 0; spanno < MAX_SPANNO; spanno++) { + char tmpbuf[BUFSIZ]; + + snprintf(tmpbuf, sizeof(tmpbuf), "%d", spanno + 1); + if (fnmatch(p, tmpbuf, 0) == 0) { + matched++; + span_specs->span_is_alaw[spanno] = is_alaw; + } + } + if (!matched) { + fprintf(stderr, + "Span specification '%s' does not match any span (item #%d inside '%s')\n", + key, i+1, spec_string); + goto err; + } + } + + /* Set defaults */ + for (spanno = 0; spanno < MAX_SPANNO; spanno++) { + if (span_specs->span_is_alaw[spanno] == TDM_CODEC_UNKNOWN) { + span_specs->span_is_alaw[spanno] = default_is_alaw; + } + } + return span_specs; +err: + free_span_specifications(span_specs); + return NULL; +} + +void print_span_specifications(struct span_specs *span_specs, FILE *output) +{ + int spanno; + + if (!span_specs) + return; + for (spanno = 0; spanno < MAX_SPANNO; spanno++) { + enum tdm_codec is_alaw; + + is_alaw = span_specs->span_is_alaw[spanno]; + fprintf(output, "%d %s\n", + spanno+1, (is_alaw == TDM_CODEC_ALAW) ? "alaw" : "ulaw"); + } +} diff --git a/xpp/parse_span_specs.h b/xpp/parse_span_specs.h new file mode 100644 index 0000000..b7dddf9 --- /dev/null +++ b/xpp/parse_span_specs.h @@ -0,0 +1,43 @@ +#ifndef PARSE_SPAN_SPECS_H +#define PARSE_SPAN_SPECS_H + +/* + * Written by Oron Peled + * Copyright (C) 2014, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#define MAX_SPANNO 4 /* E1/T1 spans -- always in first unit. 1-based */ + +enum tdm_codec { + TDM_CODEC_UNKNOWN, + TDM_CODEC_ULAW, + TDM_CODEC_ALAW, +}; + +struct span_specs { + char *buf; + enum tdm_codec span_is_alaw[MAX_SPANNO]; +}; + +struct span_specs *parse_span_specifications(const char *spec_string, int default_is_alaw); +void free_span_specifications(struct span_specs *span_specs); +void print_span_specifications(struct span_specs *span_specs, FILE *output); + +#endif /* PARSE_SPAN_SPECS_H */ diff --git a/xpp/perl_modules/Dahdi.pm b/xpp/perl_modules/Dahdi.pm new file mode 100644 index 0000000..c3bb2bc --- /dev/null +++ b/xpp/perl_modules/Dahdi.pm @@ -0,0 +1,78 @@ +package Dahdi; +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use Dahdi::Span; + +=head1 NAME + +Dahdi - Perl interface to Dahdi information + +This package allows access from Perl to information about Dahdi +hardware and loaded Dahdi devices. + +=head1 SYNOPSIS + + # Listing channels in analog spans: + use Dahdi; + # scans system: + my @spans = Dahdi::spans(); + for my $span (@spans) { + next if ($span->is_digital); + $span->num. " - [". $span->type ."] ". $span->name. "\n"; + for my $chan ($span->chans) { + print " - ".$chan->num . " - [". $chan->type. "] ". $chan->fqn". \n"; + } + } +=cut + +our $virt_base; +our $proc_dahdi_base; +our $proc_usb_base; +our $sys_base; + +=head1 spans() + +Returns a list of span objects, ordered by span number. + +=cut + +sub spans() { + my @spans; + + -d $proc_dahdi_base or return (); + foreach my $zfile (glob "$proc_dahdi_base/*") { + next unless ($zfile =~ m{^$proc_dahdi_base/\d+$}); + my $span = Dahdi::Span->new($zfile); + push(@spans, $span); + } + @spans = sort { $a->num <=> $b->num } @spans; + return @spans; +} + +=head1 ENVIRONMENT + +If C is set in the environment, it will be considered +as a path to a directory that holds a dump (copy) of all the required +files from /proc and /sys . You can generate that directory using the +script C . + +=head1 SEE ALSO + +Span objects: L. + +Dahdi channels objects: L. + +Dahdi hardware devices information: L. + +Xorcom Astribank -specific information: L. + +=cut + +1; diff --git a/xpp/perl_modules/Dahdi/Chans.pm b/xpp/perl_modules/Dahdi/Chans.pm new file mode 100644 index 0000000..8a43f58 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Chans.pm @@ -0,0 +1,264 @@ +package Dahdi::Chans; +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use Dahdi::Utils; + +=head1 NAME + +Dahdi::Chans - Perl interface to a Dahdi channel information + +This package allows access from perl to information about a Dahdi +channel. It is part of the Dahdi Perl package. + +=head1 alarms() + +In an array context returns a list of alarm strings (RED, BLUE, etc.) +for this channel (an empty list == false if there are no alarms). +In scalar context returns the number of alarms for a specific channel. + +=head1 battery() + +Returns 1 if channel reports to have battery (A remote PBX connected to +an FXO port), 0 if channel reports to not have battery and C +otherwise. + +Currently only wcfxo and Astribank FXO modules report battery. For the +rest of the channels + +=head1 fqn() + +(Fully Qualified Name) Returns the full "name" of the channel. + +=head1 index() + +Returns the number of this channel (in the span). + +=head1 num() + +Returns the number of this channel as a Dahdi channel. + +=head signalling() + +Returns the signalling set for this channel through /etc/dahdi/system.conf . +This is always empty before dahdi_cfg was run. And shows the "other" type +for FXS and for FXO. + +=head1 span() + +Returns a reference to the span to which this channel belongs. + +=head1 type() + +Returns the type of the channel: 'FXS', 'FXO', 'EMPTY', etc. + +=cut + +my @alarm_types = qw(BLUE YELLOW RED LOOP RECOVERING NOTOPEN); + +# Taken from dahdi-base.c +my @sigtypes = ( + "FXSLS", + "FXSKS", + "FXSGS", + "FXOLS", + "FXOKS", + "FXOGS", + "E&M-E1", + "E&M", + "Clear", + "HDLCRAW", + "HDLCFCS", + "HDLCNET", + "Hardware-assisted HDLC", + "MTP2", + "Slave", + "CAS", + "DACS", + "DACS+RBS", + "SF (ToneOnly)", + "Unconfigured", + "Reserved" + ); + +sub new($$$$$$) { + my $pack = shift or die "Wasn't called as a class method\n"; + my $span = shift or die "Missing a span parameter\n"; + my $index = shift; + my $line = shift or die "Missing an input line\n"; + defined $index or die "Missing an index parameter\n"; + my $self = { + 'SPAN' => $span, + 'INDEX' => $index, + }; + bless $self, $pack; + my ($num, $fqn, $rest) = split(/\s+/, $line, 3); + $num or die "Missing a channel number parameter\n"; + $fqn or die "Missing a channel fqn parameter\n"; + my $signalling = ''; + my @alarms = (); + my $info = ''; + if(defined $rest) { + # remarks in parenthesis (In use), (no pcm) + while($rest =~ s/\s*(\([^)]+\))\s*/ /) { + $info .= " $1"; + } + # Alarms + foreach my $alarm (@alarm_types) { + if($rest =~ s/\s*(\b${alarm}\b)\s*/ /) { + push(@alarms, $1); + } + } + foreach my $sig (@sigtypes) { + if($rest =~ s/^\Q$sig\E/ /) { + $signalling = $sig; + last; + } + } + warn "Unrecognized garbage '$rest' in $fqn\n" + if $rest =~ /\S/; + } + $self->{NUM} = $num; + $self->{FQN} = $fqn; + $self->{SIGNALLING} = $signalling; + $self->{ALARMS} = \@alarms; + $self->{INFO} = $info; + my $type; + if($fqn =~ m|\bXPP_(\w+)/.*$|) { + $type = $1; # An Astribank + } elsif ($fqn =~ m{\bWCFXO/.*}) { + $type = "FXO"; # wcfxo - x100p and relatives. + # A single port card. The driver issue RED alarm when + # There's no better + $self->{BATTERY} = !($span->description =~ /\bRED\b/); + } elsif ($fqn =~ m{\bFXS/.*}) { + $type = "FXS"; # likely Rhino + } elsif ($fqn =~ m{\bFXO/.*}) { + $type = "FXO"; # likely Rhino + } elsif ($fqn =~ m{---/.*}) { + $type = "EMPTY"; # likely Rhino, empty slot. + } elsif ($fqn =~ m{\b(WCTE|TE[24]|WCT1|WCT13x|Tor2|TorISA|WP[TE]1|cwain[12]|R[124]T1|AP40[124]|APE40[124])/.*}) { + # TE[24]: Digium wct4xxp + # WCT1: Digium single span card drivers? + # Tor2: Tor PCI cards + # TorISA: ISA ones (still used?) + # WP[TE]1: Sangoma. TODO: this one tells us if it is TE or NT. + # cwain: Junghanns E1 card. + # R[124]: Rhino r1t1/rxt1 cards + # AP40[124]: Aligera AP40X cards + # APE40[124]: Aligera APE40X cards + $type = "PRI"; + } elsif ($fqn =~ m{\b(WCBRI|B4|ZTHFC\d*|ztqoz\d*)/.*}) { + # WCBRI: The Digium Hx8 series cards with BRI module. + # B4: The Digium wcb4xxp DAHDI driver + # ZTHFC: HFC-s single-port card (zaphfc/vzaphfc) + # ztqoz: qozap (Junghanns) multi-port HFC card + $type = "BRI"; + } elsif ($fqn =~ m{\bDYN/.*}) { + # DYN : Dynamic span (TDMOE) + $type = "DYN" + } elsif ($fqn =~ m{\bztgsm/.*}) { + # Junghanns GSM card + $type = "GSM"; + } elsif($signalling ne '') { + $type = 'FXO' if $signalling =~ /^FXS/; + $type = 'FXS' if $signalling =~ /^FXO/; + } else { + $type = $self->probe_type(); + } + $self->type($type); + $self->span()->type($type) + if ! defined($self->span()->type()) || + $self->span()->type() eq 'UNKNOWN'; + return $self; +} + +=head1 probe_type() + +In the case of some cards, the information in /proc/dahdi is not good +enough to tell the type of each channel. In this case an extra explicit +probe is needed. + +Currently this is implemented by using some invocations of dahdi_cfg(8). + +It may later be replaced by dahdi_scan(8). + +=cut + +my $dahdi_cfg = $ENV{DAHDI_CFG} || '/usr/sbin/dahdi_cfg'; +sub probe_type($) { + my $self = shift; + my $fqn = $self->fqn; + my $num = $self->num; + my $type; + + if($fqn =~ m:WCTDM/|WRTDM/|OPVXA1200/:) { + my %maybe; + + undef %maybe; + foreach my $sig (qw(fxo fxs)) { + my $cmd = "echo ${sig}ks=$num | $dahdi_cfg -c /dev/fd/0"; + + $maybe{$sig} = system("$cmd >/dev/null 2>&1") == 0; + } + if($maybe{fxo} and $maybe{fxs}) { + $type = 'EMPTY'; + } elsif($maybe{fxo}) { + $type = 'FXS'; + } elsif($maybe{fxs}) { + $type = 'FXO'; + } else { + $type = 'EMPTY'; + } + } else { + $type = $self->type; + } + return $type; +} + +sub battery($) { + my $self = shift or die; + my $span = $self->span or die; + + return undef unless defined $self->type && $self->type eq 'FXO'; + return $self->{BATTERY} if defined $self->{BATTERY}; + + my $xpd = Dahdi::Xpp::xpd_of_span($span); + my $index = $self->index; + return undef if !$xpd; + + # It's an XPD (FXO) + my @lines = @{$xpd->lines}; + my $line = $lines[$index]; + return $line->battery; +} + +sub alarms($) { + my $self = shift or die; + my @alarms = @{$self->{ALARMS}}; + + return @alarms; +} + +sub blink($$) { + my $self = shift or die; + my $on = shift; + my $span = $self->span or die; + + my $xpd = Dahdi::Xpp::xpd_of_span($span); + my $index = $self->index; + return undef if !$xpd; + + my @lines = @{$xpd->lines}; + my $line = $lines[$index]; + return $line->blink($on); +} + + +1; diff --git a/xpp/perl_modules/Dahdi/Config/Gen.pm b/xpp/perl_modules/Dahdi/Config/Gen.pm new file mode 100644 index 0000000..cc439de --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Gen.pm @@ -0,0 +1,275 @@ +package Dahdi::Config::Gen; +# +# Written by Oron Peled +# Copyright (C) 2009, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# + +=head1 NAME + +Dahdi::Config::Gen -- Wrapper class for configuration generators. + +=head1 SYNOPSIS + + use Dahdi::Config::Gen qw(is_true); + my $params = Dahdi::Config::Params->new('the-config-file'); + my $gconfig = Dahdi::Config::Gen->new($params); + my $num = $gconfig->{'base_exten'}; + my $overlap = is_true($gconfig->{'brint_overlap'}); + $gconfig->dump; # For debugging + $gconfig->run_generator('system', {}, @spans); + +=head1 DESCRIPTION + +The constructor must be given an C object. +The returned object contains all data required for generation in the +form of a hash. + +The constructor maps the Cs from the parameter object into semantic +configuration keys. E.g: the C item is mapped to C and +C keys. + +The actual generation is done by delegation to one of the generators. +This is done via the C method which receive the +generator name, a generator specific options hash and a list of +span objects (from C) for which to generate configuration. + +This module contains few helper functions. E.g: C, C. + +=cut + +require Exporter; +@ISA = qw(Exporter); + +@EXPORT_OK = qw(is_true); + +use strict; + +# Parse values as true/false +sub is_true($) { + my $val = shift; + return undef unless defined $val; + return $val =~ /^(1|y|yes)$/i; +} + +sub range_string($$) { + my ($start, $end) = @_; + + if($start == $end) { + sprintf "%d", $start; + } else { + sprintf "%d-%d", $start, $end; + } +} + +# Generate channel range strings from arrays of chan numbers +# E.g: "63-77,79-93" +sub channo_range(@) { + my @channos = sort { $a <=> $b } @_; + my $first_num = $channos[0]; + my $range_start = $first_num; + my @range; + my $prev = undef; + + foreach my $c (@channos) { + my $curr = $c; + if(!defined($prev)) { + # First iteration + $prev = $curr; + } elsif($curr != $prev + 1) { + # New range + push(@range, range_string($range_start, $prev)); + $range_start = $curr; + } + $prev = $curr; + } + if($prev >= $first_num) { + # Last range + push(@range, range_string($range_start, $prev)); + } + return join(',', @range); +} + +# Generate channel range strings from chan objects +# E.g: "63-77,79-93" +sub chan_range(@) { + my @chans = sort { $a->num <=> $b->num } @_; + my @channos = map { $_->num } @chans; + channo_range(@channos); +} + +# Generate channel range strings from digital span objects +# E.g: "63-77,79-93" +sub bchan_range($) { + my $span = shift || die; + die unless $span->is_digital(); + my $first_chan = ($span->chans())[0]; + my $first_num = $first_chan->num(); + my $bchan_ref = $span->bchan_list(); + my @channos = map { $_ + $first_num } @{$bchan_ref}; + channo_range(@channos); +} + +# Returns a channel numbers array from a channel range string +sub parse_chan_range($) { + my $rangestr = shift; + $rangestr =~ s/\s*//g; # Squeeze + die "Bad characters in '$rangestr'" if $rangestr =~ /[^\d\s,-]/; + my @ranges = split(/,/, $rangestr); + my @channos; + my $last_end; + + foreach my $range (@ranges) { + my ($start, $end) = split(/-/, $range, 2); + $end = $start unless defined $end; + die "Bad characters in '$start'" if $start =~ /\D/; + die "Bad characters in '$end'" if $end =~ /\D/; + die "Reversed range $end < $start" if $end < $start; + die "Channel number < 1" if $start < 1; + die "New range begins below previous $start <= $last_end" if defined($last_end) && $last_end >= $start; + for(my $i = $start + 0; $i <= $end; $i++) { + push(@channos, $i); + } + $last_end = $end; + } + return sort { $a <=> $b } @channos; +} + +sub new($) { + my $pack = shift || die "$0: Missing package argument"; + my $p = shift || die "$0: Missing parameters argument"; + + # Set defaults + my $fxs_default_start = $p->item('fxs_default_start'); + my $fxo_default_start = $p->item('fxo_default_start'); + + my %default_context = ( + FXO => $p->item('context_lines'), + FXS => $p->item('context_phones'), + IN => $p->item('context_input'), + OUT => $p->item('context_output'), + DYN => $p->item('context_lines'), + BRI_TE => $p->item('context_lines'), + BRI_NT => $p->item('context_lines'), + E1_TE => $p->item('context_lines'), + T1_TE => $p->item('context_lines'), + J1_TE => $p->item('context_lines'), + E1_NT => $p->item('context_lines'), + T1_NT => $p->item('context_lines'), + J1_NT => $p->item('context_lines'), + ); + my %default_group = ( + FXO => $p->item('group_lines'), + FXS => $p->item('group_phones'), + IN => '', + OUT => '', + DYN => '', + BRI_TE => $p->item('group_lines'), + BRI_NT => $p->item('group_lines'), + E1_TE => $p->item('group_lines'), + T1_TE => $p->item('group_lines'), + J1_TE => $p->item('group_lines'), + E1_NT => $p->item('group_lines'), + T1_NT => $p->item('group_lines'), + J1_NT => $p->item('group_lines'), + ); + my %default_dahdi_signalling = ( + FXO => "fxs$fxo_default_start", + FXS => "fxo$fxs_default_start", + IN => "fxo$fxs_default_start", + OUT => "fxo$fxs_default_start", + DYN => "clear", + ); + my %default_chan_dahdi_signalling = ( + FXO => "fxs_$fxo_default_start", + FXS => "fxo_$fxs_default_start", + IN => "fxo_$fxs_default_start", + OUT => "fxo_$fxs_default_start", + DYN => "auto", # Cheating. Won't really work + ); + + # First complex mapping + my $gconfig = { + PARAMETERS => $p, + 'loadzone' => $p->item('lc_country'), + 'defaultzone' => $p->item('lc_country'), + 'context' => \%default_context, + 'group' => \%default_group, + 'dahdi_signalling' => \%default_dahdi_signalling, + 'chan_dahdi_signalling' => \%default_chan_dahdi_signalling, + }; + # Now add trivial mappings + my @trivial = qw( + base_exten + freepbx + fxs_immediate + bri_hardhdlc + bri_sig_style + r2_idle_bits + tdm_framing + echo_can + brint_overlap + pri_termtype + pri_connection_type + em_signalling + ); + foreach my $k (@trivial) { + $gconfig->{$k} = $p->item($k); + } + bless $gconfig,$pack; + + return $gconfig; +} + +sub run_generator($$@) { + my $gconfig = shift || die; + my $name = shift || die "$0: Missing generator name argument"; + my $genopts = shift || die "$0: Missing genopts argument"; + ref($genopts) eq 'HASH' or die "$0: Bad genopts argument"; + my @spans = @_; + + my $module = "Dahdi::Config::Gen::$name"; + #print STDERR "DEBUG: $module\n"; + eval "use $module"; + if($@) { + die "Failed to load configuration generator for '$name': $@\n"; + } + my $cfg = $module->new($gconfig, $genopts); + $cfg->generate(@spans); +} + +sub dump($) { + my $self = shift || die; + printf STDERR "%s dump:\n", ref $self; + my $width = 30; + foreach my $k (sort keys %$self) { + my $val = $self->{$k}; + my $ref = ref $val; + #print STDERR "DEBUG: '$k', '$ref', '$val'\n"; + if($ref eq '') { + printf STDERR "%-${width}s %s\n", $k, $val; + } elsif($ref eq 'SCALAR') { + printf STDERR "%-${width}s %s\n", $k, ${$val}; + } elsif($ref eq 'ARRAY') { + #printf STDERR "%s:\n", $k; + my $i = 0; + foreach my $v (@{$val}) { + printf STDERR "%-${width}s %s\n", "$k\->[$i]", $v; + $i++; + } + } elsif($ref eq 'HASH') { + #printf STDERR "%s:\n", $k; + foreach my $k1 (keys %{$val}) { + printf STDERR "%-${width}s %s\n", "$k\->\{$k1\}", ${$val}{$k1}; + } + } else { + printf STDERR "%-${width}s (-> %s)\n", $k, $ref; + } + } +} + + +1; diff --git a/xpp/perl_modules/Dahdi/Config/Gen/Assignedspans.pm b/xpp/perl_modules/Dahdi/Config/Gen/Assignedspans.pm new file mode 100644 index 0000000..a92eead --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Gen/Assignedspans.pm @@ -0,0 +1,63 @@ +package Dahdi::Config::Gen::Assignedspans; +use strict; + +use Dahdi::Config::Gen qw(is_true); + +sub new($$$) { + my $pack = shift || die; + my $gconfig = shift || die; + my $genopts = shift || die; + my $file = $ENV{ASSIGNED_SPANS_CONF_FILE} || "/etc/dahdi/assigned-spans.conf"; + my $self = { + FILE => $file, + GCONFIG => $gconfig, + GENOPTS => $genopts, + }; + bless $self, $pack; + return $self; +} + +sub generate($$$) { + my $self = shift || die; + my $file = $self->{FILE}; + my $gconfig = $self->{GCONFIG}; + my $genopts = $self->{GENOPTS}; + my @spans = @_; + + # If the span_types utilities were not installed we do not want to run + # this generator or report any errors. + system "which dahdi_span_assignments > /dev/null 2>&1"; + return if $?; + + warn "Empty configuration -- no spans\n" unless @spans; + rename "$file", "$file.bak" + or $! == 2 # ENOENT (No dependency on Errno.pm) + or die "Failed to backup old config: $!\n"; + #$gconfig->dump; + print "Generating $file\n" if $genopts->{verbose}; + my $cmd = "dahdi_span_assignments dumpconfig > $file"; + system $cmd; + die "Command failed (status=$?): '$cmd'" if $?; +} + +1; + +__END__ + +=head1 NAME + +dahdi - Generate configuration for dahdi drivers. + +=head1 SYNOPSIS + + use Dahdi::Config::Gen::Dahdi; + + my $cfg = new Dahdi::Config::Gen::Dahdi(\%global_config, \%genopts); + $cfg->generate(@span_list); + +=head1 DESCRIPTION + +Generate the F. +This is the configuration for dahdi_span_assignments. + +Its location may be overriden via the environment variable F. diff --git a/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm b/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm new file mode 100644 index 0000000..252b91e --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm @@ -0,0 +1,299 @@ +package Dahdi::Config::Gen::Chandahdi; +use strict; + +use Dahdi::Config::Gen qw(is_true); + +sub new($$$) { + my $pack = shift || die; + my $gconfig = shift || die; + my $genopts = shift || die; + my $file = $ENV{CHAN_DAHDI_CHANNELS_FILE} || "/etc/asterisk/dahdi-channels.conf"; + my $self = { + FILE => $file, + GCONFIG => $gconfig, + GENOPTS => $genopts, + }; + bless $self, $pack; + return $self; +} + +# Since chan_dahdi definitions "leak" to the next ones, we try +# To reset some important definitions to their chan_dahdi defaults. +my %chan_dahdi_defaults = ( + context => 'default', + group => '63', # FIXME: should not be needed. + overlapdial => 'no', + busydetect => 'no', + rxgain => 0, + txgain => 0, +); + +sub reset_chandahdi_values { + foreach my $arg (@_) { + if (exists $chan_dahdi_defaults{$arg}) { + print "$arg = $chan_dahdi_defaults{$arg}\n"; + } else { + print "$arg =\n"; + } + } +} + +sub gen_openr2($$$) { + my $self = shift || die; + my $gconfig = shift || die; + my $span = shift || die; + my $num = $span->num() || die; + my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n"; + my $type = $span->type; + # Fake type for signalling + my $faketype = ($termtype eq 'TE') ? 'E1_TE' : 'E1_TE'; + my $group = $gconfig->{'group'}{"$type"}; + die "$0: missing default group (termtype=$termtype)\n" unless defined($group); + my $context = $gconfig->{'context'}{"$faketype"}; + die "$0: missing default context\n" unless $context; + my @to_reset = qw/context group/; + my $chans = Dahdi::Config::Gen::bchan_range($span); + $group .= "," . (10 + $num); # Invent unique group per span + my $country = $gconfig->{'loadzone'}; + my @valid_countries = qw( ar br cn cz co ec itu mx ph ve ); + die "Country '$country' is invalid for R2. Use one of: @valid_countries\n" + unless grep { $_ eq $country } @valid_countries; + printf "group=$group\n"; + printf "context=$context\n"; + printf "switchtype = %s\n", $span->switchtype; + printf "signalling = %s\n", 'mfcr2'; + printf "caller = %s\n", ($termtype eq 'TE') ? 'no' : 'yes'; + printf "mfcr2_logdir = span%d\n", $span->num; + print <<"EOF"; +mfcr2_variant=$country +mfcr2_get_ani_first=no +mfcr2_max_ani=10 +mfcr2_max_dnis=4 +mfcr2_category=national_subscriber +mfcr2_call_files=yes +mfcr2_logging=all +mfcr2_mfback_timeout=-1 +mfcr2_metering_pulse_timeout=-1 +EOF + printf "channel => %s\n", $chans; + + reset_chandahdi_values(@to_reset); +} + +sub gen_cas($$$) { + my $self = shift || die; + my $gconfig = shift || die; + my $span = shift || die; + my $num = $span->num() || die; + my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n"; + my $type = $span->type; + my $group = $gconfig->{'group'}{"$type"}; + die "$0: missing default group (termtype=$termtype)\n" unless defined($group); + my $context = $gconfig->{'context'}{"$type"}; + die "$0: missing default context\n" unless $context; + # Fake type for signalling + my $faketype = ($termtype eq 'TE') ? 'FXO' : 'FXS'; + my $sig = $gconfig->{'chan_dahdi_signalling'}{$faketype}; + my $em_signalling = $gconfig->{'em_signalling'}; + if ($em_signalling ne 'none') { + $sig = $em_signalling; + # FIXME: but we don't handle E1 yet + $sig = 'em_e1' if $span->proto eq 'E1'; + } + my @to_reset = qw/context group/; + my $chans = Dahdi::Config::Gen::chan_range($span->chans()); + $group .= "," . (10 + $num); # Invent unique group per span + printf "group=$group\n"; + printf "context=$context\n"; + printf "switchtype = %s\n", $span->switchtype; + printf "signalling = %s\n", $sig; + printf "channel => %s\n", $chans; + reset_chandahdi_values(@to_reset); +} + +sub gen_digital($$$) { + my $self = shift || die; + my $gconfig = shift || die; + my $span = shift || die; + my $num = $span->num() || die; + die "Span #$num is analog" unless $span->is_digital(); + if($span->is_pri && $gconfig->{'pri_connection_type'} eq 'R2') { + printf "; Skipped: $gconfig->{'pri_connection_type'}\n\n"; + return; + } + my $type = $span->type() || die "$0: Span #$num -- unkown type\n"; + my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n"; + my $group = $gconfig->{'group'}{"$type"}; + my $context = $gconfig->{'context'}{"$type"}; + my @to_reset = qw/context group/; + + die "$0: missing default group (termtype=$termtype)\n" unless defined($group); + die "$0: missing default context\n" unless $context; + + my $sig = $span->signalling || die "missing signalling info for span #$num type $type"; + grep($gconfig->{'bri_sig_style'} eq $_, 'bri', 'bri_ptmp', 'pri') or die "unknown signalling style for BRI"; + if($span->is_bri() and $gconfig->{'bri_sig_style'} eq 'bri_ptmp') { + $sig .= '_ptmp'; + } + if ($span->is_bri() && $termtype eq 'NT' && is_true($gconfig->{'brint_overlap'})) { + print "overlapdial = yes\n"; + push(@to_reset, qw/overlapdial/); + } + + $group .= "," . (10 + $num); # Invent unique group per span + printf "group=$group\n"; + printf "context=$context\n"; + printf "switchtype = %s\n", $span->switchtype; + printf "signalling = %s\n", $sig; + printf "channel => %s\n", Dahdi::Config::Gen::bchan_range($span); + reset_chandahdi_values(@to_reset); +} + +sub gen_channel($$) { + my $self = shift || die; + my $chan = shift || die; + my $gconfig = $self->{GCONFIG}; + my $type = $chan->type; + my $num = $chan->num; + die "channel $num type $type is not an analog channel\n" if $chan->span->is_digital(); + my $exten = $gconfig->{'base_exten'} + $num; + my $sig = $gconfig->{'chan_dahdi_signalling'}{$type}; + my $context = $gconfig->{'context'}{$type}; + my $group = $gconfig->{'group'}{$type}; + my $callerid; + my $immediate; + + return if $type eq 'EMPTY'; + die "missing default_chan_dahdi_signalling for chan #$num type $type" unless $sig; + die "missing context for chan #$num type $type" unless $context; + $callerid = ($type eq 'FXO') + ? 'asreceived' + : sprintf "\"Channel %d\" <%d>", $num, $exten; + if($type eq 'IN') { + $immediate = 'yes'; + } + # FIXME: $immediage should not be set for 'OUT' channels, but meanwhile + # it's better to be compatible with genzaptelconf + $immediate = 'yes' if $gconfig->{'fxs_immediate'} eq 'yes' and $sig =~ /^fxo_/; + my $signalling = $chan->signalling; + $signalling = " " . $signalling if $signalling; + my $info = $chan->info; + $info = " " . $info if $info; + printf ";;; line=\"%d %s%s%s\"\n", $num, $chan->fqn, $signalling, $info; + printf "signalling=$sig\n"; + printf "callerid=$callerid\n"; + printf "mailbox=%d\n", $exten unless $type eq 'FXO'; + if(defined $group) { + printf "group=$group\n"; + } + printf "context=$context\n"; + printf "immediate=$immediate\n" if defined $immediate; + printf "channel => %d\n", $num; + # Reset following values to default + printf "callerid=\n"; + printf "mailbox=\n" unless $type eq 'FXO'; + if(defined $group) { + printf "group=\n"; + } + printf "context=default\n"; + printf "immediate=no\n" if defined $immediate; + print "\n"; +} + +sub generate($) { + my $self = shift || die; + my $file = $self->{FILE}; + my $gconfig = $self->{GCONFIG}; + my $genopts = $self->{GENOPTS}; + #$gconfig->dump; + my @spans = @_; + warn "Empty configuration -- no spans\n" unless @spans; + rename "$file", "$file.bak" + or $! == 2 # ENOENT (No dependency on Errno.pm) + or die "Failed to backup old config: $!\n"; + print "Generating $file\n" if $genopts->{verbose}; + open(F, ">$file") || die "$0: Failed to open $file: $!\n"; + my $old = select F; + printf "; Autogenerated by $0 on %s\n", scalar(localtime); + print "; If you edit this file and execute $0 again,\n"; + print "; your manual changes will be LOST.\n"; + print <<"HEAD"; +; Dahdi Channels Configurations (chan_dahdi.conf) +; +; This is not intended to be a complete chan_dahdi.conf. Rather, it is intended +; to be #include-d by /etc/chan_dahdi.conf that will include the global settings +; + +HEAD + foreach my $span (@spans) { + printf "; Span %d: %s %s\n", $span->num, $span->name, $span->description; + if($span->is_digital) { + if($span->is_pri) { + if($gconfig->{'pri_connection_type'} eq 'R2') { + $self->gen_openr2($gconfig, $span); + } elsif($gconfig->{'pri_connection_type'} eq 'CAS') { + $self->gen_cas($gconfig, $span); + } else { + $self->gen_digital($gconfig, $span); + } + } elsif($span->is_bri) { + $self->gen_digital($gconfig, $span); + } + } else { + foreach my $chan ($span->chans()) { + if(is_true($genopts->{'freepbx'}) || is_true($gconfig->{'freepbx'})) { + # Freepbx has its own idea about channels + my $type = $chan->type; + if($type eq 'FXS' || $type eq 'OUT' || $type eq 'IN') { + printf "; Skip channel=%s($type) -- freepbx option.\n", + $chan->num; + next; + } + } + $self->gen_channel($chan); + } + } + print "\n"; + } + close F; + select $old; +} + +1; + +__END__ + +=head1 NAME + +chandahdi - Generate configuration for chan_dahdi channels. + +=head1 SYNOPSIS + + use Dahdi::Config::Gen::Chandahdi; + + my $cfg = new Dahdi::Config::Gen::Chandahdi(\%global_config, \%genopts); + $cfg->generate(@span_list); + +=head1 DESCRIPTION + +Generate the F +This is used as a configuration for asterisk(1). +It should be included in the main F. + +Its location may be overriden via the environment variable +C. + +=head1 OPTIONS + +=over 4 + +=item freepbx + +With this option we do not generate channel definitions for FXS, Input and +Output ports. This is done because these channel definitions need to be +generated and inserted into I database anyway. + +=back + +The I option may be activated also by adding a C line +to the C file. diff --git a/xpp/perl_modules/Dahdi/Config/Gen/Freepbxdb.pm b/xpp/perl_modules/Dahdi/Config/Gen/Freepbxdb.pm new file mode 100644 index 0000000..52e7bc9 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Gen/Freepbxdb.pm @@ -0,0 +1,116 @@ +package Dahdi::Config::Gen::Freepbxdb; + +# Written by Tzafrir Cohen +# Copyright (C) 2011, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. + +use strict; +use Socket; +use Dahdi::Config::Gen qw(is_true); + +sub new($$$) { + my $pack = shift || die; + my $gconfig = shift || die; + my $genopts = shift || die; + my $self = { + GCONFIG => $gconfig, + GENOPTS => $genopts, + }; + bless $self, $pack; + return $self; +} + +sub gen_channel($$) { + my $self = shift || die; + my $chan = shift || die; + my $gconfig = $self->{GCONFIG}; + my $type = $chan->type; + my $num = $chan->num; + die "channel $num type $type is not an analog channel\n" if $chan->span->is_digital(); + my $exten = $gconfig->{'base_exten'} + $num; + my $callerid = sprintf "\"Channel %d\" <%04d>", $num, $exten; + my @cmds = (); + #push @cmds, "database put DEVICE/$exten default_user $exten"; + #push @cmds, "database put DEVICE/$exten dial ZAP/$num"; + push @cmds, "database put DEVICE/$exten dial DAHDI/$num"; + #push @cmds, "database put DEVICE/$exten type fixed"; + push @cmds, "database put DEVICE/$exten user $exten"; + push @cmds, "database put AMPUSER/$exten device $exten"; + push @cmds, "database put AMPUSER/$exten cidname $callerid"; + return @cmds; +} + +sub generate($) { + my $self = shift || die; + my $gconfig = $self->{GCONFIG}; + my $genopts = $self->{GENOPTS}; + #$gconfig->dump; + my $ast_sock = '/var/run/asterisk/asterisk.ctl'; + my @spans = @_; + my @cmds = (); + warn "Empty configuration -- no spans\n" unless @spans; + print "Configuring FXSs for FreePBX\n" if $genopts->{verbose}; + foreach my $span (@spans) { + next if $span->is_digital; + foreach my $chan ($span->chans()) { + next unless ($chan->type eq 'FXS'); + push @cmds, $self->gen_channel($chan); + } + } + #open(CMDS,"|$command >/dev/null") or + socket(SOCK, PF_UNIX, SOCK_STREAM, 0) || die "socket: $!"; + connect(SOCK, sockaddr_un($ast_sock)) || + die "$0: Freepbxdb: Failed connecting to $ast_sock\n: $!"; + foreach (@cmds) { + # Note: commands are NULL-terminated: + print SOCK "$_\0"; + sleep 0.001; + } + close(SOCK) or + die "$0: Freepbxdb: Failed sending commands ($ast_sock): $!\n"; +} + +1; + +__END__ + +=head1 NAME + +freepbxdb - Generate astdb configuration required by FreePBX + +=head1 SYNOPSIS + + use Dahdi::Config::Gen::Freepbxdb; + + my $cfg = new Dahdi::Config::Gen::Freepbxdb(\%global_config, \%genopts); + $cfg->generate(@span_list); + +=head1 DESCRIPTION + +Updates the Asterisk DB entries for FXS channels detected. Requires +Asterisk running. + +The configuration generated here bypasses FreePBX's standard configuration +and allows using a simple dialplan snippet such as: + + [from-internal-custom](+) + exten => _4XXX,1,Dial(DAHDI/${EXTEN:1}) + +This may come in handy in testing. At least until FreePBX will provide a +simple automated interface to do the same. + +=head1 OPTIONS + +None, so far. + +=head1 FILES + +=over + +=item C + +The socket to which commands are sent. FIXME: make this a parameter. + +=back + diff --git a/xpp/perl_modules/Dahdi/Config/Gen/Modules.pm b/xpp/perl_modules/Dahdi/Config/Gen/Modules.pm new file mode 100644 index 0000000..c00e3eb --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Gen/Modules.pm @@ -0,0 +1,62 @@ +package Dahdi::Config::Gen::Modules; +use strict; + +use Dahdi::Config::Gen qw(is_true); + +sub new($$$) { + my $pack = shift || die; + my $gconfig = shift || die; + my $genopts = shift || die; + my $file = $ENV{DAHDI_MODULES_FILE} || "/etc/dahdi/modules"; + my $self = { + FILE => $file, + GCONFIG => $gconfig, + GENOPTS => $genopts, + }; + bless $self, $pack; + return $self; +} + +sub generate($$$) { + my $self = shift || die; + my $file = $self->{FILE}; + my $gconfig = $self->{GCONFIG}; + my $genopts = $self->{GENOPTS}; + rename "$file", "$file.bak" + or $! == 2 # ENOENT (No dependency on Errno.pm) + or die "Failed to backup old config: $!\n"; + #$gconfig->dump; + print "Generating $file\n" if $genopts->{verbose}; + open(F, ">$file") || die "$0: Failed to open $file: $!\n"; + my $old = select F; + printf "# Autogenerated by $0 (%s) on %s\n", __PACKAGE__, scalar(localtime); + print "# If you edit this file and execute $0 again,\n"; + print "# your manual changes will be LOST.\n"; + my @drivers = Dahdi::Hardware->drivers; + print join("\n", @drivers),"\n"; + close F; + select $old; +} + +1; + +__END__ + +=head1 NAME + +modules - Generate list of dahdi drivers to load at startup + +=head1 SYNOPSIS + + use Dahdi::Config::Gen::Dahdi; + + my $cfg = new Dahdi::Config::Gen::Modules(\%global_config, \%genopts); + $cfg->generate(@span_list); + +=head1 DESCRIPTION + +Generate the F. This is a list of modules, one per +line. This list is normally used by F. + +Its location may be overriden via the environment variable +F. diff --git a/xpp/perl_modules/Dahdi/Config/Gen/Spantypes.pm b/xpp/perl_modules/Dahdi/Config/Gen/Spantypes.pm new file mode 100644 index 0000000..b1914bb --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Gen/Spantypes.pm @@ -0,0 +1,86 @@ +package Dahdi::Config::Gen::Spantypes; +use strict; + +use Dahdi::Config::Gen qw(is_true); + +sub new($$$) { + my $pack = shift || die; + my $gconfig = shift || die; + my $genopts = shift || die; + my $file = $ENV{SPAN_TYPES_CONF_FILE} || "/etc/dahdi/span-types.conf"; + my $self = { + FILE => $file, + GCONFIG => $gconfig, + GENOPTS => $genopts, + }; + bless $self, $pack; + return $self; +} + +sub generate($$$) { + my $self = shift || die; + my $file = $self->{FILE}; + my $gconfig = $self->{GCONFIG}; + my $genopts = $self->{GENOPTS}; + my @spans = @_; + + # If the dahdi_span_types utilities were not installed we do not want to run + # this generator or report any errors. + system "which dahdi_span_types > /dev/null 2>&1"; + return if $?; + + my $line_mode = $genopts->{'line-mode'}; + my $cmd; + if (defined $line_mode) { + $line_mode =~ /^[ETJ]1$/ or die "Bad line-mode='$line_mode'\n"; + $cmd = "dahdi_span_types --line-mode=$line_mode dumpconfig > $file"; + printf("Generating $file (with default line-mode %s)\n", $line_mode) + if $genopts->{verbose}; + } else { + $cmd = "dahdi_span_types dumpconfig > $file"; + printf("Generating $file (no --line-mode override)\n") + if $genopts->{verbose}; + } + rename "$file", "$file.bak" + or $! == 2 # ENOENT (No dependency on Errno.pm) + or die "Failed to backup old config: $!\n"; + #$gconfig->dump; + system $cmd; + die "Command failed (status=$?): '$cmd'" if $?; +} + +1; + +__END__ + +=head1 NAME + +dahdi - Generate configuration for dahdi drivers. + +=head1 SYNOPSIS + + use Dahdi::Config::Gen::Dahdi; + + my $cfg = new Dahdi::Config::Gen::Dahdi(\%global_config, \%genopts); + $cfg->generate(@span_list); + +=head1 DESCRIPTION + +Generate the F. +This is the configuration for dahdi_span_types. + +Its location may be overriden via the environment variable F. + +You would normally run: + + dahdi_genconf --line-mode= + +which is a short for: + + dahdi_genconf spantypes=line-mode= + +This is done by running: + dahdi_span_types dumpconfig --line-mode=line_mode> + +where I is the module parameter, and defaults to B if not +given (running C). diff --git a/xpp/perl_modules/Dahdi/Config/Gen/System.pm b/xpp/perl_modules/Dahdi/Config/Gen/System.pm new file mode 100644 index 0000000..cb7b14b --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Gen/System.pm @@ -0,0 +1,277 @@ +package Dahdi::Config::Gen::System; +use strict; + +use Dahdi::Config::Gen qw(is_true); + +sub new($$$) { + my $pack = shift || die; + my $gconfig = shift || die; + my $genopts = shift || die; + my $file = $ENV{DAHDI_CONF_FILE} || "/etc/dahdi/system.conf"; + my $self = { + FILE => $file, + GCONFIG => $gconfig, + GENOPTS => $genopts, + }; + bless $self, $pack; + return $self; +} + +my $bri_te_last_timing = 1; + +sub print_echo_can($$) { + my $gconfig = shift || die; + my $chans = shift || die; # channel or range of channels. + my $echo_can = $gconfig->{'echo_can'}; + return if !defined($echo_can) || $echo_can eq 'none'; + + print "echocanceller=$echo_can,$chans\n"; +} + +sub gen_t1_cas($$) { + my $self = shift || die; + my $gconfig = shift || die; + my $parameters = $gconfig->{PARAMETERS} || die; + my $genconf_file = $parameters->{GENCONF_FILE} || die; + my $span = shift || die; + my $num = $span->num() || die; + my $proto = $span->proto || die; + die "Generate configuration for '$proto' is not possible. Maybe you meant R2?" + unless $proto eq 'T1'; + my $pri_connection_type = $gconfig->{pri_connection_type} || die; + die "Span #$num is analog" unless $span->is_digital(); + die "Span #$num is not CAS" unless $span->is_pri && $pri_connection_type eq 'CAS'; + my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n"; + my $timing; + my $lbo = 0; + my $framing = $gconfig->{tdm_framing}; + if(!defined $framing) { + $framing = 'esf'; + } elsif($framing ne 'esf' && $framing ne 'd4') { + die "T1-CAS valid framing is only 'esf' or 'd4'. Not '$framing'. Check '$genconf_file'\n"; + } + my $coding = $span->coding() || die "$0: No coding information for span #$num\n"; + my $span_crc4 = $span->crc4(); + $span_crc4 = (defined $span_crc4) ? ",$span_crc4" : ''; + my $span_yellow = $span->yellow(); + $span_yellow = (defined $span_yellow) ? ",$span_yellow" : ''; + $timing = ($termtype eq 'NT') ? 0 : $bri_te_last_timing++; + printf "span=%d,%d,%d,%s,%s%s%s\n", + $num, + $timing, + $lbo, + $framing, + $coding, + $span_crc4, + $span_yellow; + printf "# termtype: %s\n", lc($termtype); + my $dchan_type; + my $chan_range; + if($span->is_pri()) { + if ($pri_connection_type eq 'PRI') { + $chan_range = Dahdi::Config::Gen::bchan_range($span); + printf "bchan=%s\n", $chan_range; + my $dchan = $span->dchan(); + printf "dchan=%d\n", $dchan->num(); + } elsif ($pri_connection_type eq 'R2' ) { + my $idle_bits = $gconfig->{'r2_idle_bits'}; + $chan_range = Dahdi::Config::Gen::bchan_range($span); + printf "cas=%s:$idle_bits\n", $chan_range; + } elsif ($pri_connection_type eq 'CAS' ) { + my $type = ($termtype eq 'TE') ? 'FXO' : 'FXS'; + my $sig = $gconfig->{'dahdi_signalling'}{$type}; + my $em_signalling = $gconfig->{'em_signalling'}; + if ($em_signalling ne 'none') { + $sig = 'e&m'; + # FIXME: but we don't handle E1 yet + $sig = 'e&me1' if $proto eq 'E1'; + } + die "unknown default dahdi signalling for chan $num type $type" unless defined $sig; + $chan_range = Dahdi::Config::Gen::chan_range($span->chans()); + printf "%s=%s\n", $sig, $chan_range; + } + } else { + die "Digital span $num is not PRI"; + } + print_echo_can($gconfig, $chan_range); +} + +sub gen_digital($$$) { + my $self = shift || die; + my $gconfig = shift || die; + my $span = shift || die; + my $num = $span->num() || die; + die "Span #$num is analog" unless $span->is_digital(); + my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n"; + my $timing; + my $lbo = 0; + my $framing = $span->framing() || die "$0: No framing information for span #$num\n"; + my $coding = $span->coding() || die "$0: No coding information for span #$num\n"; + my $span_crc4 = $span->crc4(); + $span_crc4 = (defined $span_crc4) ? ",$span_crc4" : ''; + my $span_yellow = $span->yellow(); + $span_yellow = (defined $span_yellow) ? ",$span_yellow" : ''; + my $span_termination = $span->termination(); + $span_termination = (defined $span_termination) ? ",$span_termination" : ''; + my $span_softntte = $span->softntte(); + $span_softntte = (defined $span_softntte) ? ",$span_softntte" : ''; + # "MFC/R2 does not normally use CRC4" + # FIXME: a finer way to override: + if ($gconfig->{'pri_connection_type'} eq 'R2') { + $span_crc4 = ''; + $framing = 'cas'; + } + $timing = ($termtype eq 'NT') ? 0 : $bri_te_last_timing++; + printf "span=%d,%d,%d,%s,%s%s%s%s%s\n", + $num, + $timing, + $lbo, + $framing, + $coding, + $span_crc4, + $span_yellow, + $span_termination, + $span_softntte; + printf "# termtype: %s\n", lc($termtype); + my $dchan_type; + if ($span->is_bri()) { + my $use_bristuff = 0; + my $cfg_hardhdlc = $gconfig->{'bri_hardhdlc'}; + my $xpd = Dahdi::Xpp::xpd_of_span($span); + if(!defined($cfg_hardhdlc) || $cfg_hardhdlc =~ /AUTO/i) { + # Autodetect + if(defined($xpd)) { + # Bristuff? + if(defined($xpd->dchan_hardhdlc) && !is_true($xpd->dchan_hardhdlc)) { + $use_bristuff = 1; + } + } + } elsif(!is_true($cfg_hardhdlc)) { + $use_bristuff = 1; + } + if($use_bristuff) { + $dchan_type = 'dchan'; + } else { + $dchan_type = 'hardhdlc'; + } + printf "bchan=%s\n", Dahdi::Config::Gen::bchan_range($span); + my $dchan = $span->dchan(); + printf "$dchan_type=%d\n", $dchan->num(); + } elsif($span->is_pri()) { + if ($gconfig->{'pri_connection_type'} eq 'PRI') { + printf "bchan=%s\n", Dahdi::Config::Gen::bchan_range($span); + my $dchan = $span->dchan(); + printf "dchan=%d\n", $dchan->num(); + } elsif ($gconfig->{'pri_connection_type'} eq 'R2' ) { + my $idle_bits = $gconfig->{'r2_idle_bits'}; + printf "cas=%s:$idle_bits\n", Dahdi::Config::Gen::bchan_range($span); + printf "dchan=%d\n", $span->dchan()->num(); + } + } else { + die "Digital span $num is not BRI, nor PRI?"; + } + print_echo_can($gconfig, Dahdi::Config::Gen::bchan_range($span)); +} + +sub gen_signalling($$) { + my $gconfig = shift || die; + my $chan = shift || die; + my $type = $chan->type; + my $num = $chan->num; + + die "channel $num type $type is not an analog channel\n" if $chan->span->is_digital(); + if($type eq 'EMPTY') { + printf "# channel %d, %s, no module.\n", $num, $chan->fqn; + return; + } + my $signalling = $gconfig->{'dahdi_signalling'}; + my $sig = $signalling->{$type} || die "unknown default dahdi signalling for chan $num type $type"; + if ($type eq 'IN') { + printf "# astbanktype: input\n"; + } elsif ($type eq 'OUT') { + printf "# astbanktype: output\n"; + } + printf "$sig=$num\n"; + print_echo_can($gconfig, $num); +} + +sub generate($$$) { + my $self = shift || die; + my $file = $self->{FILE}; + my $gconfig = $self->{GCONFIG}; + my $genopts = $self->{GENOPTS}; + my @spans = @_; + warn "Empty configuration -- no spans\n" unless @spans; + rename "$file", "$file.bak" + or $! == 2 # ENOENT (No dependency on Errno.pm) + or die "Failed to backup old config: $!\n"; + #$gconfig->dump; + print "Generating $file\n" if $genopts->{verbose}; + open(F, ">$file") || die "$0: Failed to open $file: $!\n"; + my $old = select F; + printf "# Autogenerated by $0 on %s\n", scalar(localtime); + print "# If you edit this file and execute $0 again,\n"; + print "# your manual changes will be LOST.\n"; + print <<"HEAD"; +# Dahdi Configuration File +# +# This file is parsed by the Dahdi Configurator, dahdi_cfg +# +HEAD + foreach my $span (@spans) { + printf "# Span %d: %s %s\n", $span->num, $span->name, $span->description; + if($span->is_digital) { + if($span->is_pri) { + if($gconfig->{'pri_connection_type'} eq 'CAS') { + $self->gen_t1_cas($gconfig, $span); + } else { + $self->gen_digital($gconfig, $span); + } + } elsif($span->is_bri) { + $self->gen_digital($gconfig, $span); + } + } else { + foreach my $chan ($span->chans()) { + if(1 || !defined $chan->type) { + my $type = $chan->probe_type; + my $num = $chan->num; + die "Failed probing type for channel $num" + unless defined $type; + $chan->type($type); + } + gen_signalling($gconfig, $chan); + } + } + print "\n"; + } + print <<"TAIL"; +# Global data + +loadzone = $gconfig->{'loadzone'} +defaultzone = $gconfig->{'defaultzone'} +TAIL + close F; + select $old; +} + +1; + +__END__ + +=head1 NAME + +dahdi - Generate configuration for dahdi drivers. + +=head1 SYNOPSIS + + use Dahdi::Config::Gen::Dahdi; + + my $cfg = new Dahdi::Config::Gen::Dahdi(\%global_config, \%genopts); + $cfg->generate(@span_list); + +=head1 DESCRIPTION + +Generate the F. +This is the configuration for dahdi_cfg(1). + +Its location may be overriden via the environment variable F. diff --git a/xpp/perl_modules/Dahdi/Config/Gen/Unicall.pm b/xpp/perl_modules/Dahdi/Config/Gen/Unicall.pm new file mode 100644 index 0000000..cb6bff0 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Gen/Unicall.pm @@ -0,0 +1,72 @@ +package Dahdi::Config::Gen::Unicall; +use strict; + +use Dahdi::Config::Gen qw(is_true); + +sub new($$$) { + my $pack = shift || die; + my $gconfig = shift || die; + my $genopts = shift || die; + my $file = $ENV{UNICALL_CHANNELS_FILE} || "/etc/asterisk/unicall-channels.conf"; + my $self = { + FILE => $file, + GCONFIG => $gconfig, + GENOPTS => $genopts, + }; + bless $self, $pack; + return $self; +} + +sub generate($) { + my $self = shift || die; + my $file = $self->{FILE}; + my $gconfig = $self->{GCONFIG}; + my $genopts = $self->{GENOPTS}; + #$gconfig->dump; + my @spans = @_; + warn "Empty configuration -- no spans\n" unless @spans; + die "Only for R2" unless $gconfig->{'pri_connection_type'} eq 'R2'; + rename "$file", "$file.bak" + or $! == 2 # ENOENT (No dependency on Errno.pm) + or die "Failed to backup old config: $!\n"; + print "Generating $file\n" if $genopts->{verbose}; + open(F, ">$file") || die "$0: Failed to open $file: $!\n"; + my $old = select F; + printf "; Autogenerated by $0 on %s\n", scalar(localtime); + print "; If you edit this file and execute $0 again,\n"; + print "; your manual changes will be LOST.\n"; + print "; This file should be #included in unicall.conf\n\n"; + foreach my $span (@spans) { + next unless $span->is_digital(); + printf "; Span %d: %s %s\n", $span->num, $span->name, $span->description; + my $idle_bits = $gconfig->{'r2_idle_bits'}; + printf "protocolend=%s\n", ($span->termtype() eq 'TE') ? 'cpe' : 'co'; + printf "channel=%s\n", Dahdi::Config::Gen::bchan_range($span); + print "\n"; + } + close F; + select $old; +} + +1; + +__END__ + +=head1 NAME + +unicall - Generate configuration for unicall channels. + +=head1 SYNOPSIS + + use Dahdi::Config::Gen::Unicall; + + my $cfg = new Dahdi::Config::Gen::Unicall(\%global_config, \%genopts); + $cfg->generate(@span_list); + +=head1 DESCRIPTION + +Generate the F to be included in +F + +Its location may be overriden via the environment variable +C. diff --git a/xpp/perl_modules/Dahdi/Config/Gen/Users.pm b/xpp/perl_modules/Dahdi/Config/Gen/Users.pm new file mode 100644 index 0000000..05a345f --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Gen/Users.pm @@ -0,0 +1,227 @@ +package Dahdi::Config::Gen::Users; +use strict; + +use File::Basename; +use Dahdi::Config::Gen qw(is_true); + +# Generate a complete users.conf for the asterisk-gui +# As the asterisk-gui provides no command-line interface of its own and +# no decent support of #include, we have no choice but to nuke users.conf +# if we're to provide a working system + +sub new($$$) { + my $pack = shift || die; + my $gconfig = shift || die; + my $genopts = shift || die; + my $file = $ENV{USERS_FILE} || "/etc/asterisk/users.conf"; + my $self = { + FILE => $file, + GCONFIG => $gconfig, + GENOPTS => $genopts, + }; + bless $self, $pack; + return $self; +} + +# A single analog trunk for all the FXO channels +sub gen_analog_trunk { + my @fxo_ports = @_; + return unless (@fxo_ports); # no ports + + my $ports = join(',', @fxo_ports); + + print << "EOF" +[trunk_1] +trunkname = analog +hasexten = no +hasiax = no +hassip = no +hasregisteriax = no +hasregistersip = no +trunkstyle = analog +dahdichan = $ports + +EOF +} + +# A digital trunk for a single span. +# FIXME: how do I create the DID context? +sub gen_digital_trunk($) { + my $span = shift; + my $num = $span->num; + my $sig = $span->signalling; + my $type = $span->type; + my $bchan_range = Dahdi::Config::Gen::bchan_range($span); + + print << "EOF"; +[span_$num] +group = $num +hasexten = no +signalling = $sig +trunkname = Span $num $type +trunkstyle = digital ; GUI metadata +hassip = no +hasiax = no +context = DID_span_$num +dahdichan = $bchan_range + +EOF +} + +my $ExtenNum; + +# A single user for a FXS channel +sub gen_channel($$) { + my $self = shift || die; + my $chan = shift || die; + my $gconfig = $self->{GCONFIG}; + my $type = $chan->type; + my $num = $chan->num; + die "channel $num type $type is not an analog channel\n" if $chan->span->is_digital(); + my $exten = $ExtenNum++; + my $sig = $gconfig->{'chan_dahdi_signalling'}{$type}; + my $full_name = "$type $num"; + + die "missing default_chan_dahdi_signalling for chan #$num type $type" unless $sig; + print << "EOF"; +[$exten] +context = DLPN_DialPlan1 +callwaiting = yes +fullname = $full_name +cid_number = $exten +hasagent = no +hasdirectory = no +hasiax = no +hasmanager = no +hassip = no +hasvoicemail = yes +mailbox = $exten +threewaycalling = yes +vmsecret = $exten +signalling = $sig +dahdichan = $num +registeriax = no +registersip = no +canreinvite = no + +EOF +} + +sub generate($) { + my $self = shift || die; + my $file = $self->{FILE}; + my $gconfig = $self->{GCONFIG}; + my $genopts = $self->{GENOPTS}; + #$gconfig->dump; + my @spans = @_; + warn "Empty configuration -- no spans\n" unless @spans; + rename "$file", "$file.bak" + or $! == 2 # ENOENT (No dependency on Errno.pm) + or die "Failed to backup old config: $!\n"; + print "Generating $file\n" if $genopts->{verbose}; + open(F, ">$file") || die "$0: Failed to open $file: $!\n"; + my $old = select F; + print <<"HEAD"; +;! +;! Automatically generated configuration file +;! Filename: @{[basename($file)]} ($file) +;! Generator: $0 +;! Creation Date: @{[scalar(localtime)]} +;! If you edit this file and execute $0 again, +;! your manual changes will be LOST. +;! +[general] +; +; Starting point of allocation of extensions +; +userbase = @{[$gconfig->{'base_exten'}+1]} +; +; Create voicemail mailbox and use use macro-stdexten +; +hasvoicemail = yes +; +; Set voicemail mailbox @{[$gconfig->{'base_exten'}+1]} password to 1234 +; +vmsecret = 1234 +; +; Create SIP Peer +; +hassip = no +; +; Create IAX friend +; +hasiax = no +; +; Create Agent friend +; +hasagent = no +; +; Create H.323 friend +; +;hash323 = yes +; +; Create manager entry +; +hasmanager = no +; +; Remaining options are not specific to users.conf entries but are general. +; +callwaiting = yes +threewaycalling = yes +callwaitingcallerid = yes +transfer = yes +canpark = yes +cancallforward = yes +callreturn = yes +callgroup = 1 +pickupgroup = 1 +localextenlength = @{[length($gconfig->{'base_exten'})]} + + +HEAD + my @fxo_ports = (); + $ExtenNum = $self->{GCONFIG}->{'base_exten'}; + foreach my $span (@spans) { + printf "; Span %d: %s %s\n", $span->num, $span->name, $span->description; + if ($span->type =~ /^(BRI_(NT|TE)|E1|T1)$/) { + gen_digital_trunk($span); + next; + } + foreach my $chan ($span->chans()) { + if (grep { $_ eq $span->type} ( 'FXS', 'IN', 'OUT' )) { + $self->gen_channel($chan); + } elsif ($chan->type eq 'FXO') { + # TODO: "$first_chan-$last_chan" + push @fxo_ports,($chan->num); + } + } + print "\n"; + } + gen_analog_trunk(@fxo_ports); + close F; + select $old; +} + +1; + +__END__ + +=head1 NAME + +users - Generate configuration for users.conf. + +=head1 SYNOPSIS + + use Dahdi::Config::Gen::Users; + + my $cfg = new Dahdi::Config::Gen::Users(\%global_config, \%genopts); + $cfg->generate(@span_list); + +=head1 DESCRIPTION + +Generate the F which is used by asterisk(1) +and AsteriskGUI. This will replace your entire configuration including +any SIP/IAX users and trunks you may have set. Thus it's probably only +appropriate for an initial setup. + +Its location may be overriden via the environment variable F. diff --git a/xpp/perl_modules/Dahdi/Config/Gen/Xpporder.pm b/xpp/perl_modules/Dahdi/Config/Gen/Xpporder.pm new file mode 100644 index 0000000..146b097 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Gen/Xpporder.pm @@ -0,0 +1,142 @@ +package Dahdi::Config::Gen::Xpporder; +use strict; + +use Dahdi::Config::Gen qw(is_true); +use Dahdi::Xpp; + +sub new($$$) { + my $pack = shift || die; + my $gconfig = shift || die; + my $genopts = shift || die; + my $file = $ENV{XPPORDER_CONF} || "/etc/dahdi/xpp_order"; + my $self = { + FILE => $file, + GCONFIG => $gconfig, + GENOPTS => $genopts, + }; + bless $self, $pack; + return $self; +} + +# +# Returns list of xbuses sorted by the span numbers assigned +# to their XPD's. Also checks that each XBUS span numbers are sequential. +sub get_sorted_xbuses(@) { + my @spans = @_; # Verify our spans + my @xbuses = Dahdi::Xpp::xbuses; + my %xbus_of_span; + my %xbus_beginning; + my %seen_spans; + my @sorted_xbuses; + foreach my $xbus (@xbuses) { + my $last_spanno; + foreach my $xpd (Dahdi::Xpp::Xpd::telephony_devs($xbus->xpds())) { + my $spanno = $xpd->spanno; + if(!$spanno) { + printf STDERR "%s: Is not registered. Skipping.\n", $xpd->fqn; + next; + } + $seen_spans{$spanno}++; + if($xbus_of_span{$spanno}) { + printf STDERR "%s: Span %d already seen on %s\n", + $xpd->fqn, $spanno, $xbus_of_span{$spanno}->name; + die; + } + $xbus_of_span{$spanno} = $xbus; + # Check XPD's sequential numbering + if(defined $last_spanno) { + if($last_spanno + 1 != $spanno) { + printf STDERR "%s: Bad span numbers (%d, %d)\n", + $xpd->fqn, $last_spanno, $spanno; + die; + } + } else { + $xbus_beginning{$xbus} = $spanno; + } + $last_spanno = $spanno; + } + } + foreach my $span (@spans) { + my $spanno = $span->num; + if(!defined($seen_spans{$spanno})) { + warn "Span $spanno: Ignored: Does not belong to any XPD\n"; + } + } + @sorted_xbuses = sort { $xbus_beginning{$a} <=> $xbus_beginning{$b} } @xbuses; + return @sorted_xbuses; +} + +sub generate($$$) { + my $self = shift || die; + my $file = $self->{FILE}; + my $gconfig = $self->{GCONFIG}; + my $genopts = $self->{GENOPTS}; + my @spans = @_; # Verify it's all our spans + my @xbuses = get_sorted_xbuses(@spans); + warn "Empty configuration -- no xbuses\n" unless @xbuses; + rename "$file", "$file.bak" + or $! == 2 # ENOENT (No dependency on Errno.pm) + or die "Failed to backup old config: $!\n"; + #$gconfig->dump; + print "Generating $file\n" if $genopts->{verbose}; + open(F, ">$file") || die "$0: Failed to open $file: $!\n"; + my $old = select F; + printf "# Autogenerated by $0 on %s\n", scalar(localtime); + print "# If you edit this file and execute $0 again,\n"; + print "# your manual changes will be LOST.\n"; + print <<'HEAD'; +# +# This is an optional configuration file for ordering +# Dahdi registration. +# +# It is read from /etc/dahdi/xpp_order. This location +# may be overridden via the environment variable XPPORDER_CONF +# +# Lines may contain: +# - The Astribank label (verbatim) +# - The Astribank connector string (prefixed with @) +# Ordering number of each listed Astribank is determined +# by its position in this file. +# Astribanks not listed in this file, get an ordering +# number of 99 (last). +# +# Astribanks with same ordering number are sorted by their +# connectors (to preserve legacy behavior). +# +# Examples: +#usb:1234 +#@usb-0000:06:02.2-2 +HEAD + foreach my $xbus (@xbuses) { + my $label = $xbus->label; + my $connector = $xbus->connector; + my $name = $xbus->name; + printf "%s\t# %s #(%s)\n", $label, $connector, $name; + } + close F; + select $old; +} + +1; + +__END__ + +=head1 NAME + +Xpporder - Generate Astribank ordering information for dahdi_registration. + +=head1 SYNOPSIS + + use Dahdi::Config::Gen::Xpporder; + + my $cfg = new Dahdi::Config::Gen::Xpporder(\%global_config, \%genopts); + $cfg->generate; + +=head1 DESCRIPTION + +Generate the F. +This is the configuration for dahdi_registration(1). +The order is determined according to current Dahdi registration +order. + +Its location may be overriden via the environment variable F. diff --git a/xpp/perl_modules/Dahdi/Config/Params.pm b/xpp/perl_modules/Dahdi/Config/Params.pm new file mode 100644 index 0000000..0cc0d88 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Params.pm @@ -0,0 +1,156 @@ +package Dahdi::Config::Params; +# +# Written by Oron Peled +# Copyright (C) 2009, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; + +=head1 NAME + +Dahdi::Config::Params -- Object oriented representation of F file. + +=head1 SYNOPSIS + + use Dahdi::Config::Params; + my $params = Dahdi::Config::Params->new('the-config-file'); + print $params->item{'some-key'}; + print $params->item{'some-key', NODEFAULTS => 1}; + $params->dump; # For debugging + +=head1 DESCRIPTION + +The constructor must be given a configuration file name: + +=over 4 + +=item * Missing file is B an error. + +=item * Other opening errors cause a C to be thrown. + +=item * The file name is saved as the value of C key. + +=back + +The access to config keys should only be done via the C method: + +=over 4 + +=item * It contains all hard-coded defaults. + +=item * All these values are overriden by directives in the config file. + +=item * Calling it with C 1> option, returns C for keys that +do not appear in the configuration file. + +=back + +=cut + +sub new($$) { + my $pack = shift || die; + my $cfg_file = shift || die; + my $self = { + GENCONF_FILE => $cfg_file, + }; + bless $self, $pack; + if(!open(F, $cfg_file)) { + if(defined($!{ENOENT})) { + #print STDERR "No $cfg_file. Assume empty config\n"; + return $self; # Empty configuration + } + die "$pack: Failed to open '$cfg_file': $!\n"; + } + #print STDERR "$pack: $cfg_file\n"; + my $array_key; + while() { + my ($key, $val); + chomp; + s/#.*$//; + s/\s+$//; # trim tail whitespace + next unless /\S/; + if(defined $array_key && /^\s+/) { + s/^\s+//; # trim beginning whitespace + push(@{$self->{$array_key}}, $_); + next; + } + undef $array_key; + ($key, $val) = split(/\s+/, $_, 2); + $key = lc($key); + if(! defined $val) { + $array_key = $key; + next; + } + die "$cfg_file:$.: Duplicate key '$key'\n", if exists $self->{$key}; + $self->{$key} = $val; + } + close F; + return $self; +} + +sub item($$@) { + my $self = shift || die; + my $key = shift || die; + my %options = @_; + my %defaults = ( + base_exten => '4000', + freepbx => 'no', # Better via -F command line + fxs_immediate => 'no', + fxs_default_start => 'ks', + fxo_default_start => 'ks', + em_signalling => 'none', + lc_country => 'us', + context_lines => 'from-pstn', + context_phones => 'from-internal', + context_input => 'astbank-input', + context_output => 'astbank-output', + group_phones => '5', + group_lines => '0', + brint_overlap => 'no', + bri_sig_style => 'bri_ptmp', + echo_can => 'mg2', + bri_hardhdlc => 'auto', + pri_connection_type => 'PRI', + r2_idle_bits => '1101', + tdm_framing => 'esf', + 'pri_termtype' => [ 'SPAN/* TE' ], + ); + return $self->{$key} if exists($self->{$key}) or $options{NODEFAULTS}; + return $defaults{$key}; +} + +sub dump($) { + my $self = shift || die; + printf STDERR "%s dump:\n", ref $self; + my $width = 30; + foreach my $k (sort keys %$self) { + my $val = $self->{$k}; + my $ref = ref $val; + #print STDERR "DEBUG: '$k', '$ref', '$val'\n"; + if($ref eq '') { + printf STDERR "%-${width}s %s\n", $k, $val; + } elsif($ref eq 'SCALAR') { + printf STDERR "%-${width}s %s\n", $k, ${$val}; + } elsif($ref eq 'ARRAY') { + #printf STDERR "%s:\n", $k; + my $i = 0; + foreach my $v (@{$val}) { + printf STDERR "%-${width}s %s\n", "$k\->[$i]", $v; + $i++; + } + } elsif($ref eq 'HASH') { + #printf STDERR "%s:\n", $k; + foreach my $k1 (keys %{$val}) { + printf STDERR "%-${width}s %s\n", "$k\->\{$k1\}", ${$val}{$k1}; + } + } else { + printf STDERR "%-${width}s (-> %s)\n", $k, $ref; + } + } +} + +1; + diff --git a/xpp/perl_modules/Dahdi/Hardware.pm b/xpp/perl_modules/Dahdi/Hardware.pm new file mode 100644 index 0000000..ba89447 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Hardware.pm @@ -0,0 +1,235 @@ +package Dahdi::Hardware; +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; + +=head1 NAME + +Dahdi::Hardware - Perl interface to a Dahdi devices listing + + + use Dahdi::Hardware; + + my $hardware = Dahdi::Hardware->scan; + + # mini dahdi_hardware: + foreach my $device ($hardware->device_list) { + print "Vendor: device->{VENDOR}, Product: $device->{PRODUCT}\n" + } + + # let's see if there are devices without loaded drivers, and sugggest + # drivers to load: + my @to_load = (); + foreach my $device ($hardware->device_list) { + if (! $device->{LOADED} ) { + push @to_load, ($device->${DRIVER}); + } + } + if (@to_load) { + print "To support the extra devices you probably need to run:\n" + print " modprobe ". (join ' ', @to_load). "\n"; + } + + +This module provides information about available Dahdi devices on the +system. It identifies devices by (USB/PCI) bus IDs. + + +=head1 Device Attributes + +As usual, object attributes can be used in either upp-case or +lower-case, or lower-case functions. + +=head2 bus_type + +'PCI' or 'USB'. + + +=head2 description + +A one-line description of the device. + + +=head2 driver + +Name of a Dahdi device driver that should handle this device. This is +based on a pre-made list. + + +=head2 vendor, product, subvendor, subproduct + +The PCI and USB vendor ID, product ID, sub-vendor ID and sub-product ID. +(The standard short lspci and lsusb listings show only vendor and +product IDs). + + +=head2 loaded + +If the device is handled by a module - the name of the module. Else - +undef. + + +=head2 priv_device_name + +A string that shows the "location" of that device on the bus. + + +=head2 is_astribank + +True if the device is a Xorcom Astribank (which may provide some extra +attributes). + +=head2 serial + +(Astribank-specific attrribute) - the serial number string of the +Astribank. + +=cut +# +# A global hardware handle +# + +my %hardware_list = ( + 'PCI' => [], + 'USB' => [], + ); + + +sub new($$) { + my $pack = shift || die "Wasn't called as a class method\n"; + my $name = shift || die "$0: Missing device name"; + my $type = shift || die "$0: Missing device type"; + my $dev = {}; + $dev->{'BUS_TYPE'} = $type; + $dev->{IS_ASTRIBANK} = 0 unless defined $dev->{'IS_ASTRIBANK'}; + $dev->{'HARDWARE_NAME'} = $name; + return $dev; +} + +=head1 device_list() + +Returns a list of the hardware devices on the system. + +You must run scan() first for this function to run meaningful output. + +=cut + +sub device_list($) { + my $pack = shift || die; + my @types = @_; + my @list; + + @types = qw(USB PCI) unless @types; + foreach my $t (@types) { + my $lst = $hardware_list{$t}; + @list = ( @list, @{$lst} ); + } + return @list; +} + +sub device_by_hwname($$) { + my $pack = shift || die; + my $name = shift || die; + my @list = device_list('localcall'); + + my @good = grep { $_->hardware_name eq $name } @list; + return undef unless @good; + @good > 1 && die "$pack: Multiple matches for '$name': @good"; + return $good[0]; +} + +=head1 drivers() + +Returns a list of drivers (currently sorted by name) that are used by +the devices in the current system (regardless to whether or not they are +loaded. + +=cut + +sub drivers($) { + my $self = shift || die; + my @devs = device_list('localcall'); + my @drvs = map { $_->{DRIVER} } @devs; + # Make unique + my %drivers; + @drivers{@drvs} = 1; + return sort keys %drivers; +} + + +=head1 scan() + +Scan the system for Dahdi devices (PCI and USB). Returns nothing but +must be run to initialize the module. + +=cut + +my $hardware_scanned; + +sub scan($) { + my $pack = shift || die; + + return if $hardware_scanned++; + foreach my $type (qw(PCI USB)) { + eval "use Dahdi::Hardware::$type"; + die $@ if $@; + $hardware_list{$type} = [ "Dahdi::Hardware::$type"->scan_devices ]; + } +} + +=head1 rescan + +Rescan for devices. In case new devices became available since the script +has started. + +=cut + +sub rescan($) { + my $pack = shift || die; + + $hardware_scanned = 0; + $pack->scan(); +} + +sub import { + Dahdi::Hardware->scan unless grep(/\bnoscan\b/i, @_); +} + +sub showall { + my $pack = shift || die; + my @devs; + + my $printer = sub { + my $title = shift; + my @devs = @_; + + return unless @devs; + printf "%s:\n", $title; + foreach my $dev (@devs) { + printf "\t%s\n", $dev->hardware_name; + foreach my $k (sort keys %{$dev}) { + my $v = $dev->{$k}; + if($k eq 'MPPINFO') { + printf "\t\tMPPINFO:\n"; + eval "use Dahdi::Xpp::Mpp"; + die $@ if $@; + $v->showinfo("\t\t "); + } else { + printf "\t\t%-20s %s\n", $k, $v; + } + } + } + }; + foreach my $type (qw(USB PCI)) { + my $lst = $hardware_list{$type}; + &$printer("$type devices", @{$lst}); + } +} + +1; diff --git a/xpp/perl_modules/Dahdi/Hardware/PCI.pm b/xpp/perl_modules/Dahdi/Hardware/PCI.pm new file mode 100644 index 0000000..aa4de51 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Hardware/PCI.pm @@ -0,0 +1,261 @@ +package Dahdi::Hardware::PCI; +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use Dahdi::Utils; +use Dahdi::Hardware; + +our @ISA = qw(Dahdi::Hardware); + +# Lookup algorithm: +# First match 'vendor:product/subvendor:subproduct' key +# Else match 'vendor:product/subvendor' key +# Else match 'vendor:product' key +# Else not a dahdi hardware. +my %pci_ids = ( + # from wct4xxp + '10ee:0314' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE410P/TE405P (1st Gen)' }, + 'd161:1420' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE420 (5th Gen)' }, + 'd161:1410' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE410P (5th Gen)' }, + 'd161:1405' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE405P (5th Gen)' }, + 'd161:0420/0004' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE420 (4th Gen)' }, + 'd161:0410/0004' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE410P (4th Gen)' }, + 'd161:0405/0004' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE405P (4th Gen)' }, + 'd161:0410/0003' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE410P (3rd Gen)' }, + 'd161:0405/0003' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE405P (3rd Gen)' }, + 'd161:0410' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE410P (2nd Gen)' }, + 'd161:0405' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE405P (2nd Gen)' }, + 'd161:1220' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE220 (5th Gen)' }, + 'd161:1205' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE205P (5th Gen)' }, + 'd161:1210' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE210P (5th Gen)' }, + 'd161:0220/0004' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE220 (4th Gen)' }, + 'd161:0205/0004' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE205P (4th Gen)' }, + 'd161:0210/0004' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE210P (4th Gen)' }, + 'd161:0205/0003' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE205P (3rd Gen)' }, + 'd161:0210/0003' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE210P (3rd Gen)' }, + 'd161:0205' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE205P ' }, + 'd161:0210' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE210P ' }, + 'd161:1820' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE820 (5th Gen)' }, + + # from wctdm24xxp + 'd161:2400' => { DRIVER => 'wctdm24xxp', DESCRIPTION => 'Wildcard TDM2400P' }, + 'd161:0800' => { DRIVER => 'wctdm24xxp', DESCRIPTION => 'Wildcard TDM800P' }, + 'd161:8002' => { DRIVER => 'wctdm24xxp', DESCRIPTION => 'Wildcard AEX800' }, + 'd161:8003' => { DRIVER => 'wctdm24xxp', DESCRIPTION => 'Wildcard AEX2400' }, + 'd161:8005' => { DRIVER => 'wctdm24xxp', DESCRIPTION => 'Wildcard TDM410P' }, + 'd161:8006' => { DRIVER => 'wctdm24xxp', DESCRIPTION => 'Wildcard AEX410P' }, + 'd161:8007' => { DRIVER => 'wctdm24xxp', DESCRIPTION => 'HA8-0000' }, + 'd161:8008' => { DRIVER => 'wctdm24xxp', DESCRIPTION => 'HB8-0000' }, + + # from pciradio + 'e159:0001/e16b' => { DRIVER => 'pciradio', DESCRIPTION => 'PCIRADIO' }, + + # from wcfxo + 'e159:0001/8084' => { DRIVER => 'wcfxo', DESCRIPTION => 'Wildcard X101P clone' }, + 'e159:0001/8085' => { DRIVER => 'wcfxo', DESCRIPTION => 'Wildcard X101P' }, + 'e159:0001/8086' => { DRIVER => 'wcfxo', DESCRIPTION => 'Wildcard X101P clone' }, + 'e159:0001/8087' => { DRIVER => 'wcfxo', DESCRIPTION => 'Wildcard X101P clone' }, + '1057:5608' => { DRIVER => 'wcfxo', DESCRIPTION => 'Wildcard X100P' }, + + # from wct1xxp + 'e159:0001/6159' => { DRIVER => 'wct1xxp', DESCRIPTION => 'Digium Wildcard T100P T1/PRI or E100P E1/PRA Board' }, + + # from wctdm + 'e159:0001/a159' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard S400P Prototype' }, + 'e159:0001/e159' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard S400P Prototype' }, + 'e159:0001/b100' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV E/F' }, + 'e159:0001/b1d9' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV I' }, + 'e159:0001/b118' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV I' }, + 'e159:0001/b119' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV I' }, + 'e159:0001/a9fd' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV H' }, + 'e159:0001/a8fd' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV H' }, + 'e159:0001/a800' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV H' }, + 'e159:0001/a801' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV H' }, + 'e159:0001/a908' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV H' }, + 'e159:0001/a901' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV H' }, + #'e159:0001' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV H' }, + + # from wcte11xp + 'e159:0001/71fe' => { DRIVER => 'wcte11xp', DESCRIPTION => 'Digium Wildcard TE110P T1/E1 Board' }, + 'e159:0001/79fe' => { DRIVER => 'wcte11xp', DESCRIPTION => 'Digium Wildcard TE110P T1/E1 Board' }, + 'e159:0001/795e' => { DRIVER => 'wcte11xp', DESCRIPTION => 'Digium Wildcard TE110P T1/E1 Board' }, + 'e159:0001/79de' => { DRIVER => 'wcte11xp', DESCRIPTION => 'Digium Wildcard TE110P T1/E1 Board' }, + 'e159:0001/797e' => { DRIVER => 'wcte11xp', DESCRIPTION => 'Digium Wildcard TE110P T1/E1 Board' }, + + # from wcte12xp + 'd161:0120' => { DRIVER => 'wcte12xp', DESCRIPTION => 'Wildcard TE12xP' }, + 'd161:8000' => { DRIVER => 'wcte12xp', DESCRIPTION => 'Wildcard TE121' }, + 'd161:8001' => { DRIVER => 'wcte12xp', DESCRIPTION => 'Wildcard TE122' }, + + # from wcte13xp + 'd161:800a' => { DRIVER => 'wcte13xp', DESCRIPTION => 'Wildcard TE131/TE133' }, + 'd161:800b' => { DRIVER => 'wcte13xp', DESCRIPTION => 'Wildcard TE132/TE134' }, + + # from wcaxx + 'd161:800c' => { DRIVER => 'wcaxx', DESCRIPTION => 'Digium A8A' }, + 'd161:800d' => { DRIVER => 'wcaxx', DESCRIPTION => 'Digium A8B' }, + 'd161:800f' => { DRIVER => 'wcaxx', DESCRIPTION => 'Digium A4A' }, + 'd161:8010' => { DRIVER => 'wcaxx', DESCRIPTION => 'Digium A4B' }, + + # from wcte435/235 + 'd161:800e' => { DRIVER => 'wcte43x', DESCRIPTION => 'Wildcard TE435/235' }, + 'd161:8013' => { DRIVER => 'wcte43x', DESCRIPTION => 'Wildcard TE436/236' }, + + # from wcb4xxp + 'd161:b410' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'Digium Wildcard B410P' }, + + # from tor2 + '10b5:9030' => { DRIVER => 'tor2', DESCRIPTION => 'PLX 9030' }, + '10b5:3001' => { DRIVER => 'tor2', DESCRIPTION => 'PLX Development Board' }, + '10b5:d00d' => { DRIVER => 'tor2', DESCRIPTION => 'Tormenta 2 Quad T1/PRI or E1/PRA' }, + '10b5:4000' => { DRIVER => 'tor2', DESCRIPTION => 'Tormenta 2 Quad T1/E1 (non-Digium clone)' }, + + # # from wctc4xxp + 'd161:3400' => { DRIVER => 'wctc4xxp', DESCRIPTION => 'Wildcard TC400P' }, + 'd161:8004' => { DRIVER => 'wctc4xxp', DESCRIPTION => 'Wildcard TCE400P' }, + + # Cologne Chips: + # (Still a partial list) + '1397:08b4/1397:b540' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'Swyx 4xS0 SX2 QuadBri' }, + '1397:08b4/1397:b556' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'Junghanns DuoBRI ISDN card' }, + '1397:08b4/1397:b520' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'Junghanns QuadBRI ISDN card' }, + '1397:08b4/1397:b550' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'Junghanns QuadBRI ISDN card' }, + '1397:08b4/1397:b752' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'Junghanns QuadBRI ISDN PCI-E card' }, + '1397:16b8/1397:b552' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'Junghanns OctoBRI ISDN card' }, + '1397:16b8/1397:b55b' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'Junghanns OctoBRI ISDN card' }, + '1397:08b4/1397:e884' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'OpenVox B200P' }, + '1397:08b4/1397:e888' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'OpenVox B400P' }, + '1397:16b8/1397:e998' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'OpenVox B800P' }, + '1397:08b4/1397:b566' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'BeroNet BN2S0' }, + '1397:08b4/1397:b560' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'BeroNet BN4S0' }, + '1397:08b4/1397:b762' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'BeroNet BN4S0 PCI-E card' }, + '1397:16b8/1397:b562' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'BeroNet BN8S0' }, + '1397:08b4' => { DRIVER => 'qozap', DESCRIPTION => 'Generic Cologne ISDN card' }, + '1397:16b8' => { DRIVER => 'qozap', DESCRIPTION => 'Generic OctoBRI ISDN card' }, + '1397:30b1' => { DRIVER => 'cwain', DESCRIPTION => 'HFC-E1 ISDN E1 card' }, + '1397:2bd0' => { DRIVER => 'zaphfc', DESCRIPTION => 'HFC-S ISDN BRI card' }, + # Has three submodels. Tested with 0675:1704: + '1043:0675' => { DRIVER => 'zaphfc', DESCRIPTION => 'ASUSTeK Computer Inc. ISDNLink P-IN100-ST-D' }, + '1397:f001' => { DRIVER => 'ztgsm', DESCRIPTION => 'HFC-GSM Cologne Chips GSM' }, + + # Rhino cards (based on pci.ids) + '0b0b:0105' => { DRIVER => 'r1t1', DESCRIPTION => 'Rhino R1T1' }, + '0b0b:0205' => { DRIVER => 'r4fxo', DESCRIPTION => 'Rhino R14FXO' }, + '0b0b:0206' => { DRIVER => 'rcbfx', DESCRIPTION => 'Rhino RCB4FXO 4-channel FXO analog telphony card' }, + '0b0b:0305' => { DRIVER => 'rxt1', DESCRIPTION => 'Rhino R4T1' }, + '0b0b:0405' => { DRIVER => 'rcbfx', DESCRIPTION => 'Rhino R8FXX' }, + '0b0b:0406' => { DRIVER => 'rcbfx', DESCRIPTION => 'Rhino RCB8FXX 8-channel modular analog telphony card' }, + '0b0b:0505' => { DRIVER => 'rcbfx', DESCRIPTION => 'Rhino R24FXX' }, + '0b0b:0506' => { DRIVER => 'rcbfx', DESCRIPTION => 'Rhino RCB24FXS 24-Channel FXS analog telphony card' }, + '0b0b:0605' => { DRIVER => 'rxt1', DESCRIPTION => 'Rhino R2T1' }, + '0b0b:0705' => { DRIVER => 'rcbfx', DESCRIPTION => 'Rhino R24FXS' }, + '0b0b:0706' => { DRIVER => 'rcbfx', DESCRIPTION => 'Rhino RCB24FXO 24-Channel FXO analog telphony card' }, + '0b0b:0906' => { DRIVER => 'rcbfx', DESCRIPTION => 'Rhino RCB24FXX 24-channel modular analog telphony card' }, + + # Sangoma cards (based on pci.ids) + '1923:0040' => { DRIVER => 'wanpipe', DESCRIPTION => 'Sangoma Technologies Corp. A200/Remora FXO/FXS Analog AFT card' }, + '1923:0100' => { DRIVER => 'wanpipe', DESCRIPTION => 'Sangoma Technologies Corp. A104d QUAD T1/E1 AFT card' }, + '1923:0300' => { DRIVER => 'wanpipe', DESCRIPTION => 'Sangoma Technologies Corp. A101 single-port T1/E1' }, + '1923:0400' => { DRIVER => 'wanpipe', DESCRIPTION => 'Sangoma Technologies Corp. A104u Quad T1/E1 AFT' }, + + # Yeastar (from output of modinfo): + 'e159:0001/2151' => { DRIVER => 'ystdm8xx', DESCRIPTION => 'Yeastar YSTDM8xx'}, + + 'e159:0001/9500:0003' => { DRIVER => 'opvxa1200', DESCRIPTION => 'OpenVox A800P' }, + + # Aligera + '10ee:1004' => { DRIVER => 'ap400', DESCRIPTION => 'Aligera AP40X/APE40X 1E1/2E1/4E1 card' }, + ); + +$ENV{PATH} .= ":/usr/sbin:/sbin:/usr/bin:/bin"; + +sub pci_sorter { + return $a->priv_device_name() cmp $b->priv_device_name(); +} + +sub new($@) { + my $pack = shift || die "Wasn't called as a class method\n"; + my %attr = @_; + my $name = sprintf("pci:%s", $attr{PRIV_DEVICE_NAME}); + my $self = Dahdi::Hardware->new($name, 'PCI'); + %{$self} = (%{$self}, %attr); + bless $self, $pack; + return $self; +} + +my %pci_devs; + +sub readfile($) { + my $name = shift || die; + open(F, $name) || die "Failed to open '$name': $!"; + my $str = ; + close F; + chomp($str); + return $str; +} + +sub scan_devices($) { + my @devices; + + while(<$Dahdi::sys_base/bus/pci/devices/*>) { + m,([^/]+)$,,; + my $name = $1; + my $l = readlink $_ || die; + $pci_devs{$name}{PRIV_DEVICE_NAME} = $name; + $pci_devs{$name}{DEVICE} = $l; + $pci_devs{$name}{VENDOR} = readfile "$_/vendor"; + $pci_devs{$name}{PRODUCT} = readfile "$_/device"; + $pci_devs{$name}{SUBVENDOR} = readfile "$_/subsystem_vendor"; + $pci_devs{$name}{SUBPRODUCT} = readfile "$_/subsystem_device"; + my $dev = $pci_devs{$name}; + grep(s/0x//, $dev->{VENDOR}, $dev->{PRODUCT}, $dev->{SUBVENDOR}, $dev->{SUBPRODUCT}); + $pci_devs{$name}{DRIVER} = ''; + } + + while(<$Dahdi::sys_base/bus/pci/drivers/*/[0-9]*>) { + m,^(.*?)/([^/]+)/([^/]+)$,; + my $prefix = $1; + my $drvname = $2; + my $id = $3; + my $l = readlink "$prefix/$drvname/module"; + # Find the real module name (if we can). + if(defined $l) { + my $moduledir = "$prefix/$drvname/$l"; + my $modname = $moduledir; + $modname =~ s:^.*/::; + $drvname = $modname; + } + $pci_devs{$id}{LOADED} = $drvname; + } + foreach (sort keys %pci_devs) { + my $dev = $pci_devs{$_}; + my $key; + # Try to match + $key = "$dev->{VENDOR}:$dev->{PRODUCT}/$dev->{SUBVENDOR}:$dev->{SUBPRODUCT}"; + $key = "$dev->{VENDOR}:$dev->{PRODUCT}/$dev->{SUBVENDOR}" if !defined($pci_ids{$key}); + $key = "$dev->{VENDOR}:$dev->{PRODUCT}" if !defined($pci_ids{$key}); + next unless defined $pci_ids{$key}; + + my $d = Dahdi::Hardware::PCI->new( + PRIV_DEVICE_NAME => $dev->{PRIV_DEVICE_NAME}, + VENDOR => $dev->{VENDOR}, + PRODUCT => $dev->{PRODUCT}, + SUBVENDOR => $dev->{SUBVENDOR}, + SUBPRODUCT => $dev->{SUBPRODUCT}, + LOADED => $dev->{LOADED}, + DRIVER => $pci_ids{$key}{DRIVER}, + DESCRIPTION => $pci_ids{$key}{DESCRIPTION}, + ); + push(@devices, $d); + } + @devices = sort pci_sorter @devices; + return @devices; +} + +1; diff --git a/xpp/perl_modules/Dahdi/Hardware/USB.pm b/xpp/perl_modules/Dahdi/Hardware/USB.pm new file mode 100644 index 0000000..c9f2ada --- /dev/null +++ b/xpp/perl_modules/Dahdi/Hardware/USB.pm @@ -0,0 +1,221 @@ +package Dahdi::Hardware::USB; +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use Dahdi::Utils; +use Dahdi::Hardware; +use Dahdi::Xpp::Mpp; + +our @ISA = qw(Dahdi::Hardware); + +my %usb_ids = ( + # from wcusb + '06e6:831c' => { DRIVER => 'wcusb', DESCRIPTION => 'Wildcard S100U USB FXS Interface' }, + '06e6:831e' => { DRIVER => 'wcusb2', DESCRIPTION => 'Wildcard S110U USB FXS Interface' }, + '06e6:b210' => { DRIVER => 'wc_usb_phone', DESCRIPTION => 'Wildcard Phone Test driver' }, + + # from xpp_usb + 'e4e4:1130' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-8/16 no-firmware' }, + 'e4e4:1131' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-8/16 USB-firmware' }, + 'e4e4:1132' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-8/16 FPGA-firmware' }, + 'e4e4:1140' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-BRI no-firmware' }, + 'e4e4:1141' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-BRI USB-firmware' }, + 'e4e4:1142' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-BRI FPGA-firmware' }, + 'e4e4:1150' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-multi no-firmware' }, + 'e4e4:1151' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-multi USB-firmware' }, + 'e4e4:1152' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-multi FPGA-firmware' }, + 'e4e4:1160' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-modular no-firmware' }, + 'e4e4:1161' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-modular USB-firmware' }, + 'e4e4:1162' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-modular FPGA-firmware' }, + 'e4e4:1163' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-TwinStar monitor' }, + 'e4e4:1164' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-EEPROM burner' }, + + # Sangoma USB FXO: + '10c4:8461' => { DRIVER => 'wanpipe', DESCRIPTION => 'Sangoma WANPIPE USB-FXO Device' }, + ); + + +$ENV{PATH} .= ":/usr/sbin:/sbin:/usr/bin:/bin"; + +sub usb_sorter() { + return $a->hardware_name cmp $b->hardware_name; +} + +sub mpp_addinfo($) { + my $self = shift || die; + + my $mppinfo = Dahdi::Xpp::Mpp->new($self); + $self->{MPPINFO} = $mppinfo if defined $mppinfo; +} + +sub new($@) { + my $pack = shift or die "Wasn't called as a class method\n"; + my %attr = @_; + my $name = sprintf("usb:%s", $attr{PRIV_DEVICE_NAME}); + my $self = Dahdi::Hardware->new($name, 'USB'); + %{$self} = (%{$self}, %attr); + bless $self, $pack; + return $self; +} + +sub readval($) { + my $fname = shift || warn; + open(F, $fname) || warn "Failed opening '$fname': $!"; + my $val = ; + close F; + chomp $val; + warn "$fname is empty" unless defined $val and $val; + return $val; +} + +sub set_transport($$) { + my $pack = shift || die; + my $xbus = shift || die; + my $xbus_dir = shift; + my $transportdir = "$xbus_dir/transport"; + if(! -e "$transportdir/ep_00") { + warn "A trasnport in '$transportdir' is not USB"; + return undef; + } + my ($usbdev) = glob("$transportdir/usb_device:*"); + my $busnum; + my $devnum; + # Different kernels... + if(defined $usbdev) { # It's USB + if($usbdev =~ /.*usb_device:usbdev(\d+)\.(\d+)/) { + $busnum = $1; + $devnum = $2; + } else { + warn "Bad USB transportdir='$transportdir' usbdev='$usbdev'\n"; + } + } elsif(-f "$transportdir/idVendor" ) { + my $transport_link = readlink($transportdir); + $transport_link =~ m|/(\d+)-[\d.]+$|; + $busnum = $1; + $devnum = readval("$transportdir/devnum"); + } + my $usbname = sprintf("%03d/%03d", $busnum, $devnum); + #printf STDERR "DEBUG: %03d/%03d\n", $busnum, $devnum; + $xbus->{USB_DEVNAME} = $usbname; + my $hwdev = Dahdi::Hardware->device_by_hwname("usb:$usbname"); + if(defined $hwdev) { + #print "set_transport: ", $hwdev, "\n"; + $xbus->{TRANSPORT} = $hwdev; + $hwdev->{XBUS} = $xbus; + $hwdev->{LOADED} = 'xpp_usb'; + $xbus->{IS_TWINSTAR} = $hwdev->is_twinstar; + } + return $hwdev; +} + +sub _get_attr($) { + my $attr_file = shift; + + open(ATTR, $attr_file) or die "Failed to read SysFS attribute $attr_file\n"; + my $value = ; + chomp $value; + return $value; +} + +sub _get_attr_optional($$) { + my ($attr_file, $def_val) = @_; + + eval {return _get_attr($attr_file)}; + + # If we got here, _get_attr exploded. Return the default value: + return $def_val; +} + +sub scan_devices_sysfs($) { + my $pack = shift || die; + my @devices = (); + + while (<$Dahdi::sys_base/bus/usb/devices/*-*>) { + next unless -r "$_/idVendor"; # endpoints + + # Older kernels, e.g. 2.6.9, don't have the attribute + # busnum: + m|/((\d+)-[\d.]+)$|; + my $busnum = $2 || next; + my $dev_sys_name = $1; + my $vendor = _get_attr("$_/idVendor"); + my $product = _get_attr("$_/idProduct"); + my $model = $usb_ids{"$vendor:$product"}; + next unless defined $model; + my $devnum = _get_attr("$_/devnum"); + my $serial = _get_attr_optional("$_/serial", ''); + my $devname = sprintf("%03d/%03d", $busnum, $devnum); + # Get driver for first interface of the device: + my $iface = "$_/$dev_sys_name:1.0"; + my $loaded = readlink("$iface/driver"); + if (defined $loaded) { + $loaded =~ s|.*/||; + } + my $d = Dahdi::Hardware::USB->new( + IS_ASTRIBANK => ($model->{DRIVER} eq 'xpp_usb')?1:0, + PRIV_DEVICE_NAME => $devname, + VENDOR => $vendor, + PRODUCT => $product, + SERIAL => $serial, + DESCRIPTION => $model->{DESCRIPTION}, + DRIVER => $model->{DRIVER}, + LOADED => $loaded, + ); + push(@devices, $d); + } + return @devices; +} + +sub scan_devices($) { + my $pack = shift || die; + my $usb_device_list = "$Dahdi::proc_usb_base/devices"; + return $pack->scan_devices_sysfs() unless (-r $usb_device_list); + + my @devices; + open(F, $usb_device_list) || die "Failed to open $usb_device_list: $!"; + local $/ = ''; + while() { + my @lines = split(/\n/); + my ($tline) = grep(/^T/, @lines); + my ($pline) = grep(/^P/, @lines); + my ($dline) = grep(/^I/, @lines); + my ($sline) = grep(/^S:.*SerialNumber=/, @lines); + my ($busnum,$devnum) = ($tline =~ /Bus=(\w+)\W.*Dev#=\s*(\w+)\W/); + my $devname = sprintf("%03d/%03d", $busnum, $devnum); + my ($vendor,$product) = ($pline =~ /Vendor=(\w+)\W.*ProdID=(\w+)\W/); + my $serial; + if(defined $sline) { + $sline =~ /SerialNumber=(.*)/; + $serial = $1; + #$serial =~ s/[[:^print:]]/_/g; + } + my $loaded; + if ($dline =~ /Driver=(\w+)/) { + $loaded = $1; + } + my $model = $usb_ids{"$vendor:$product"}; + next unless defined $model; + my $d = Dahdi::Hardware::USB->new( + IS_ASTRIBANK => ($model->{DRIVER} eq 'xpp_usb')?1:0, + PRIV_DEVICE_NAME => $devname, + VENDOR => $vendor, + PRODUCT => $product, + SERIAL => $serial, + DESCRIPTION => $model->{DESCRIPTION}, + DRIVER => $model->{DRIVER}, + LOADED => $loaded, + ); + push(@devices, $d); + } + close F; + @devices = sort usb_sorter @devices; + return @devices; +} + +1; diff --git a/xpp/perl_modules/Dahdi/Span.pm b/xpp/perl_modules/Dahdi/Span.pm new file mode 100644 index 0000000..69c5d03 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Span.pm @@ -0,0 +1,420 @@ +package Dahdi::Span; +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use Dahdi::Utils; +use Dahdi::Chans; + +=head1 NAME + +Dahdi::Spans - Perl interface to a Dahdi span information + +This package allows access from perl to information about a Dahdi +channel. It is part of the Dahdi Perl package. + +A span is a logical unit of Dahdi channels. Normally a port in a +digital card or a whole analog card. + +See documentation of module L for usage example. Specifically +C must be run initially. + +=head1 by_number() + +Get a span by its Dahdi span number. + +=head1 Span Properties + +=head2 num() + +The span number. + +=head2 name() + +The name field of a Dahdi span. E.g.: + + TE2/0/1 + +=head2 description() + +The description field of the span. e.g: + + "T2XXP (PCI) Card 0 Span 1" HDB3/CCS/CRC4 RED + +=head2 chans() + +The list of the channels (L objects) of this span. +In a scalar context returns the number of channels this span has. + +=head2 bchans() + +Likewise a list of bchannels (or a count in a scalar context). + +=head2 is_sync_master() + +Is this span the source of timing for Dahdi? + +=head2 type() + +Type of span, or "UNKNOWN" if could not be detected. Current known +types: + +BRI_TE, BRI_NT, E1_TE, E1_NT, J1_TE, J1_NT, T1_TE, T1_NT, FXS, FXO + +=head2 is_pri() + +Is this an E1/J1/T1 span? + +=head2 is_bri() + +Is this a BRI span? + +=head2 is_digital() + +Is this a digital (as opposed to analog) span? + +=head2 termtype() + +Set for digital spans. "TE" or "NT". Will probably be assumed to be "TE" +if there's no information pointing either way. + +=head2 coding() + +Suggested sane coding type (e.g.: "hdb3", "b8zs") for this type of span. + +=head2 framing() + +Suggested sane framing type (e.g.: "ccs", "esf") for this type of span. + +=head2 yellow(), crc4() + +Likewise, suggestions ofr the respective fields in the span= line in +/etc/dahdi/system.conf for this span. + +=head2 signalling() + +Suggested chan_dahdi.conf signalling for channels of this span. + +=head2 switchtype() + +Suggested chan_dahdi.conf switchtype for channels of this span. + +=head1 Note + +Most of those properties are normally used as lower-case functions, but +actually set in the module as capital-letter propeties. To look at e.g. +"signalling" is set, look for "SIGNALLING". + +=cut + +sub chans($) { + my $span = shift; + return @{$span->{CHANS}}; +} + +sub by_number($) { + my $span_number = shift; + die "Missing span number" unless defined $span_number; + my @spans = Dahdi::spans(); + + my ($span) = grep { $_->num == $span_number } @spans; + return $span; +} + +my @bri_strings = ( + 'BRI_(NT|TE)', + '(?:quad|octo)BRI PCI ISDN Card.* \[(NT|TE)\]', + 'octoBRI \[(NT|TE)\] ', + 'HFC-S PCI A ISDN.* \[(NT|TE)\] ', + '(B4XXP) \(PCI\) Card', # Use dahdi_scan to determine TE/NT mode + '(WCBRI)', # has selectable NT/TE modes via dahdi_cfg + ); + +my @pri_strings = ( + 'Tormenta 2 .*Quad (E1|T1)', # tor2. + 'Xorcom XPD.*: (E1|T1)', # Astribank PRI + 'Digium Wildcard .100P (T1|E1)/', # wct1xxp + 'ISA Tormenta Span 1', # torisa + 'TE110P T1/E1', # wcte11xp + 'Wildcard TE120P', # wcte12xp + 'Wildcard TE121', # wcte12xp + 'Wildcard TE122', # wcte12xp + 'Wildcard TE131/TE133', # wcte13xp + 'Wildcard TE132/TE134', # wcte13xp + 'T[248]XXP \(PCI\) Card ', # wct4xxp + 'WCTE43X \(PCI\) Card ', # wcte43xp + 'WCTE23X \(PCI\) Card ', # wcte43xp + 'R[24]T1 \(PCI\) Card', # rxt1 + 'Rhino R1T1 (E1)/PRA Card', # r1t1 + 'Rhino R1T1 (T1)/PRI Card', # r1t1 + 'WP(E1|T1)/.* "wanpipe', # Sangoma E1/T1 + ); + +my @soft_term_type_strings = ( + 'Xorcom XPD.*: (E1|T1)', # Astribank PRI + '(WCBRI)', # has selectable NT/TE modes via dahdi_cfg +); + +our $DAHDI_BRI_NET = 'bri_net'; +our $DAHDI_BRI_CPE = 'bri_cpe'; + +our $DAHDI_PRI_NET = 'pri_net'; +our $DAHDI_PRI_CPE = 'pri_cpe'; + +sub init_proto($$) { + my $self = shift; + my $proto = shift; + + $self->{PROTO} = $proto; + if($proto eq 'E1') { + $self->{DCHAN_IDX} = 15; + $self->{BCHAN_LIST} = [ 0 .. 14, 16 .. 30 ]; + } elsif($proto eq 'T1') { + $self->{DCHAN_IDX} = 23; + $self->{BCHAN_LIST} = [ 0 .. 22 ]; + } + $self->{TYPE} = "${proto}_$self->{TERMTYPE}"; +} + +sub get_digital_spantype { + my $span_no = shift; + my @lines = split /\n/, `dahdi_scan`; + my $found_span = 0; + foreach my $line (@lines) { + if (! $found_span) { + if ($line =~ m/\[$span_no\]/) { + $found_span = 1; + } + } else { + if ($line !~ m/^\[/) { + if ($line =~ m/digital-(TE|NT)/ ){ + return $1; + } + } else { + $found_span = 0; + } + } + } + die "Cannot determine digital spantype"; +} + +sub new($$) { + my $pack = shift or die "Wasn't called as a class method\n"; + my $proc_file = shift or die "Missing a proc file parameter\n"; + $proc_file =~ m{[^/]*/(\d+)$}; + my $num = $1 or die " Invalid span file name: $proc_file\n"; + my $self = { NUM => $num }; + bless $self, $pack; + $self->{TYPE} = "UNKNOWN"; + open(F, "$proc_file") or die "Failed to open '$proc_file\n"; + my $head = ; + chomp $head; + $self->{IS_DIGITAL} = 0; + $self->{IS_BRI} = 0; + $self->{IS_PRI} = 0; + $self->{TERMTYPE} = "UNKNOWN"; + foreach my $cardtype (@bri_strings) { + if($head =~ m/$cardtype/) { + my $termtype = $1; + if ($1 eq 'B4XXP') { + $termtype = get_digital_spantype($num); + } + if ($1 eq 'WCBRI') { + $termtype = 'TE'; + } + $self->{IS_DIGITAL} = 1; + $self->{IS_BRI} = 1; + $self->{TERMTYPE} = $termtype; + $self->{TYPE} = "BRI_$termtype"; + $self->{DCHAN_IDX} = 2; + $self->{BCHAN_LIST} = [ 0, 1 ]; + $self->init_proto('BRI'); + last; + } + } + foreach my $cardtype (@pri_strings) { + if($head =~ m/$cardtype/) { + my @info; + + push(@info, $1) if defined $1; + push(@info, $2) if defined $2; + my ($proto) = grep(/(E1|T1|J1)/, @info); + $proto = 'UNKNOWN' unless defined $proto; + my ($termtype) = grep(/(NT|TE)/, @info); + $termtype = 'UNKNOWN' unless defined $termtype; + + $self->{IS_DIGITAL} = 1; + $self->{IS_PRI} = 1; + $self->{TERMTYPE} = $termtype; + $self->init_proto($proto); + last; + } + } + $self->{IS_SOFT_TERM_TYPE} = 0; + foreach my $cardtype (@soft_term_type_strings) { + if($head =~ m/$cardtype/) { + $self->{IS_SOFT_TERM_TYPE} = 1; + last; + } + } + + if (($self->is_soft_term_type == 0) and ($self->termtype eq "UNKNOWN")) { + $self->{IS_SOFT_TERM_TYPE} = 1; + } + + ($self->{NAME}, $self->{DESCRIPTION}) = (split(/\s+/, $head, 4))[2, 3]; + $self->{IS_DAHDI_SYNC_MASTER} = + ($self->{DESCRIPTION} =~ /\(MASTER\)/) ? 1 : 0; + $self->{CHANS} = []; + my @channels; + my $index = 0; + my @channel_lines = ; + foreach (@channel_lines) { + chomp; + s/^\s*//; + s/\s*$//; + next unless /\S/; + next unless /^\s*\d+/; # must be a real channel string. + my $c = Dahdi::Chans->new($self, $index, $_); + push(@channels, $c); + $index++; + } + close F; + if($self->is_pri()) { + # Check for PRI with unknown type strings + if($index == 31) { + if($self->{PROTO} eq 'UNKNOWN') { + $self->init_proto('E1'); + } elsif($self->{PROTO} ne 'E1') { + die "$index channels in a $self->{PROTO} span"; + } + } elsif($index == 24) { + if($self->{PROTO} eq 'UNKNOWN') { + $self->init_proto('T1'); # FIXME: J1? + } elsif($self->{PROTO} ne 'T1') { + die "$index channels in a $self->{PROTO} span"; + } + } + } + @channels = sort { $a->num <=> $b->num } @channels; + $self->{CHANS} = \@channels; + $self->{YELLOW} = undef; + $self->{CRC4} = undef; + $self->{SOFTNTTE} = undef; + $self->{TERMINATION} = undef; + if($self->is_bri()) { + $self->{CODING} = 'ami'; + $self->{DCHAN} = ($self->chans())[$self->{DCHAN_IDX}]; + $self->{BCHANS} = [ ($self->chans())[@{$self->{BCHAN_LIST}}] ]; + # Infer some info from channel name: + my $first_chan = ($self->chans())[0] || die "$0: No channels in span #$num\n"; + my $chan_fqn = $first_chan->fqn(); + if($chan_fqn =~ m(ZTHFC.*/|ztqoz.*/|XPP_BRI_.*|B4/.*|WCBRI/.*)) { # BRI + if($chan_fqn =~ m(WCBRI/.*)) { # make sure to set termination resistors on hybrid cards + $self->{TERMINATION} = 'term'; + $self->{SOFTNTTE} = 'te'; + } + $self->{FRAMING} = 'ccs'; + $self->{SWITCHTYPE} = 'euroisdn'; + $self->{SIGNALLING} = ($self->{TERMTYPE} eq 'NT') ? $DAHDI_BRI_NET : $DAHDI_BRI_CPE ; + } elsif($chan_fqn =~ m(ztgsm.*/)) { # Junghanns's GSM cards. + $self->{FRAMING} = 'ccs'; + $self->{SIGNALLING} = 'gsm'; + } + } + if($self->is_pri()) { + $self->{DCHAN} = ($self->chans())[$self->{DCHAN_IDX}]; + $self->{BCHANS} = [ ($self->chans())[@{$self->{BCHAN_LIST}}] ]; + if($self->{PROTO} eq 'E1') { + $self->{CODING} = 'hdb3'; + $self->{FRAMING} = 'ccs'; + $self->{SWITCHTYPE} = 'euroisdn'; + $self->{CRC4} = 'crc4'; + } elsif($self->{PROTO} eq 'T1') { + $self->{CODING} = 'b8zs'; + $self->{FRAMING} = 'esf'; + $self->{SWITCHTYPE} = 'national'; + } else { + die "'$self->{PROTO}' unsupported yet"; + } + } + return $self; +} + +sub bchans($) { + my $self = shift || die; + + return @{$self->{BCHANS}}; +} + +sub set_termtype($$) { + my $span = shift || die; + my $termtype = shift || die; + $span->{TERMTYPE} = $termtype; + if ($span->is_pri) { + $span->{SIGNALLING} = ($termtype eq 'NT') ? $DAHDI_PRI_NET : $DAHDI_PRI_CPE ; + } elsif ($span->is_bri) { + $span->{SIGNALLING} = ($termtype eq 'NT') ? $DAHDI_BRI_NET : $DAHDI_BRI_CPE ; + } + $span->{TYPE} = $span->proto . "_$termtype"; +} + +sub pri_set_fromconfig($$) { + my $span = shift || die; + my $genconf = shift || die; + my $name = $span->name; + return unless $span->is_soft_term_type; +# if(defined $termtype) { +# die "Termtype for $name already defined as $termtype\n"; +# } + my $pri_termtype = $genconf->{pri_termtype}; + my @pri_specs; + if(defined $pri_termtype) { + @pri_specs = @{$pri_termtype}; + } + push(@pri_specs , 'SPAN/* TE'); # Default + my @patlist = ( "SPAN/" . $span->num ); + my $xpd = Dahdi::Xpp::xpd_of_span($span); + if(defined $xpd) { + my $xbus = $xpd->xbus; + my $xbus_name = $xbus->name; + my $xpd_name = "XPD-" . $xpd->id; + my $label = $xbus->label; + my $connector = $xbus->connector; + #print "DEBUG: '$xbus_name/$xpd_name' LABEL='$label' CONNECTOR='$connector'\n"; + push(@patlist, "NUM/$xbus_name/$xpd_name"); + push(@patlist, "LABEL/$label/$xpd_name"); + push(@patlist, "CONNECTOR/$connector/$xpd_name"); + } + #print STDERR "PATLIST=@patlist\n"; + my $match_termtype; +SPEC: + for(my $i = 0; $i < @pri_specs; $i++) { + my $spec = $pri_specs[$i]; + #print STDERR "spec: $spec\n"; + my ($match, $termtype) = split(/\s+/, $spec); + next unless defined $match and defined $termtype; + # Convert "globs" to regex + $match =~ s/\*/.*/g; + $match =~ s/\?/./g; + #print STDERR "match: $match\n"; + foreach my $pattern (@patlist) { + #print STDERR "testmatch: $pattern =~ $match\n"; + if($pattern =~ /^$match$/) { + #print STDERR "MATCH '$pattern' ~ '$match' termtype=$termtype\n"; + $match_termtype = $termtype; + last SPEC; + } + } + } + die "Unknown pri_termtype" unless defined $match_termtype; + $span->set_termtype($match_termtype); +} + + +1; diff --git a/xpp/perl_modules/Dahdi/Utils.pm b/xpp/perl_modules/Dahdi/Utils.pm new file mode 100644 index 0000000..31b1be7 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Utils.pm @@ -0,0 +1,65 @@ +package Dahdi::Utils; + +# Accessors (miniperl does not have Class:Accessor) +our $AUTOLOAD; +sub AUTOLOAD { + my $self = shift; + my $name = $AUTOLOAD; + $name =~ s/.*://; # strip fully-qualified portion + return if $name =~ /^[A-Z_]+$/; # ignore special methods (DESTROY) + my $key = uc($name); + my $val = shift; + if (defined $val) { + #print STDERR "set: $key = $val\n"; + return $self->{$key} = $val; + } else { + if(!exists $self->{$key}) { + #$self->xpp_dump; + #die "Trying to get uninitialized '$key'"; + } + my $val = $self->{$key}; + #print STDERR "get: $key ($val)\n"; + return $val; + } +} + +# Initialize ProcFS and SysFS pathes, in case the user set +# DAHDI_VIRT_TOP +BEGIN { + if (exists $ENV{DAHDI_VIRT_TOP}) { + $Dahdi::virt_base = $ENV{DAHDI_VIRT_TOP}; + } else { + $Dahdi::virt_base = ''; + } + $Dahdi::proc_dahdi_base = "$Dahdi::virt_base/proc/dahdi"; + $Dahdi::proc_usb_base = "$Dahdi::virt_base/proc/bus/usb"; + $Dahdi::sys_base = "$Dahdi::virt_base/sys"; +} + +sub xpp_dump($) { + my $self = shift || die; + printf STDERR "Dump a %s\n", ref($self); + foreach my $k (sort keys %{$self}) { + my $val = $self->{$k}; + $val = '**UNDEF**' if !defined $val; + printf STDERR " %-20s %s\n", $k, $val; + } +} + +# Based on Autoloader + +sub import { + my $pkg = shift; + my $callpkg = caller; + + #print STDERR "import: $pkg, $callpkg\n"; + # + # Export symbols, but not by accident of inheritance. + # + die "Sombody inherited Dahdi::Utils" if $pkg ne 'Dahdi::Utils'; + no strict 'refs'; + *{ $callpkg . '::AUTOLOAD' } = \&AUTOLOAD; + *{ $callpkg . '::xpp_dump' } = \&xpp_dump; +} + +1; diff --git a/xpp/perl_modules/Dahdi/Xpp.pm b/xpp/perl_modules/Dahdi/Xpp.pm new file mode 100644 index 0000000..3acd2ef --- /dev/null +++ b/xpp/perl_modules/Dahdi/Xpp.pm @@ -0,0 +1,307 @@ +package Dahdi::Xpp; +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use Dahdi::Hardware; +use Dahdi::Xpp::Xbus; + +=head1 NAME + +Dahdi::Xpp - Perl interface to the Xorcom Astribank drivers. + +=head1 SYNOPSIS + + # Listing all Astribanks: + use Dahdi::Xpp; + # scans hardware: + my @xbuses = Dahdi::Xpp::xbuses("SORT_CONNECTOR"); + for my $xbus (@xbuses) { + print $xbus->name." (".$xbus->label .", ". $xbus->connector .")\n"; + for my $xpd ($xbus->xpds) { + print " - ".$xpd->fqn,"\n"; + } + } +=cut + +# +# A global handle for all xbuses +# +my @xbuses; + +our $sysfs_astribanks; +our $sysfs_xpds; +our $sysfs_ab_driver; + +BEGIN { + my $virt_base = $Dahdi::virt_base; + $sysfs_astribanks = "$virt_base/sys/bus/astribanks/devices"; + $sysfs_xpds = "$virt_base/sys/bus/xpds/devices"; + $sysfs_ab_driver = "$virt_base/sys/bus/astribanks/drivers/xppdrv"; +} + +sub scan($) { + my $pack = shift || die; + + opendir(D, $sysfs_astribanks) || return(); + while(my $entry = readdir D) { + next if $entry eq '.' or $entry eq '..'; + my $xbus = Dahdi::Xpp::Xbus->new($sysfs_astribanks, $entry); + push(@xbuses, $xbus); + } + closedir D; + return @xbuses; +} + +# Nominal sorters for xbuses +sub by_name { + return $a->name cmp $b->name; +} + +sub by_connector { + return $a->connector cmp $b->connector; +} + +sub by_label { + my $cmp = $a->label cmp $b->label; + return $cmp if $cmp != 0; + return $a->connector cmp $b->connector; +} + +sub score_type { + my $score; + + return 1 if grep(/\b[ETJ]1/, @_); + return 2 if grep(/\bBRI/, @_); + return 3 if grep(/\bFXO/, @_); + return 4; # FXS +} + +sub by_type { + my @a_types = map { $_->type } $a->xpds(); + my @b_types = map { $_->type } $b->xpds(); + my $res; + + my $a_score = score_type(@a_types); + my $b_score = score_type(@b_types); + #printf STDERR "DEBUG-a: %s %s %s\n", $a->name, $a_score, join(',',@a_types); + #printf STDERR "DEBUG-b: %s %s %s\n", $b->name, $b_score, join(',',@b_types); + $res = $a_score <=> $b_score; + $res = $a->connector cmp $b->connector if $res == 0; + return $res; +} + +sub by_xpporder { + my $cmp = $a->xpporder <=> $b->xpporder; + return $cmp if $cmp != 0; + return $a->connector cmp $b->connector; +} + +=head1 xbuses([sort_order]) + +Scans system (via /sys) and returns a list of Astribank (Xbus) +objects. The optional parameter sort_order is the order in which +the Astribanks will be returns: + + +=head1 sorters([sort_order]) + +With no parameters, returns the names of built in sorters. +With a single parameter, returns a reference to the requested built in sorter. +Also, for convenience, a reference to a custom sorter function may be passed +and returned as is. + +The built in sorters are: + +=over + +=item SORT_XPPORDER + +Sort by ordering defined in F file. +Astribanks can be listed in this file by their label or by +their connector string (prefixed with <@>). + +Astribanks not listed in the F file are sorted +via ordering number 999 -- So they come after the Astribanks +that are listed. + +Astribanks with same ordering number (e.g: 999) are sorted +by their connector string (to preserve legacy behaviour). + +=item SORT_CONNECTOR + +Sort by the connector string. For USB this defines the "path" to get to +the device through controllers, hubs etc. + +=item SORT_LABEL + +Sorts by the label of the Astribank. The label field is unique to the +Astribank. It can also be viewed through 'lsusb -v' without the drivers +loaded (the iSerial field in the Device Descriptor). This is normally +relieble, but some older Astribanks have an empty label. + +=item SORT_NAME + +Sort by the "name". e.g: "XBUS-00". The order of Astribank names depends +on the load order, and hence may change between different runs. + +=item SORT_TYPE + +Sort by XPD types. First Astribanks with E1/T1/J1 XPDs, then with BRI, +then with FXO, then ones with only FXS ports. Within each type they +are sorted by the connector field (as in SORT_CONNECTOR above). + +=item custom function + +Instead of using a predefined sorter, you can pass your own sorting +function. See the example sorters in the code of this module. + +=back + +=cut + +sub sorters { + my %sorter_table = ( + SORT_CONNECTOR => \&by_connector, + SORT_NAME => \&by_name, + SORT_LABEL => \&by_label, + SORT_TYPE => \&by_type, + SORT_XPPORDER => \&by_xpporder, + # Aliases + connector => \&by_connector, + name => \&by_name, + label => \&by_label, + type => \&by_type, + xpporder => \&by_xpporder, + ); + my $which_sorter = shift || return sort keys %sorter_table; + return $which_sorter if ref($which_sorter) eq 'CODE'; + return $sorter_table{$which_sorter}; +} + +sub add_xpporder(@) { + my @xbuses = @_; + my $cfg = $ENV{XPPORDER_CONF} || '/etc/dahdi/xpp_order'; + my %order; + + # Set defaults + foreach my $xbus (@xbuses) { + $xbus->{XPPORDER} = 99; + } + # Read from optional config file + if(!open(F, $cfg)) { + warn "$0: Failed opening '$cfg': $!" + unless $! == 2; # ENOENT + return; + } + my $count = 1; + while() { + chomp; + s/#.*//; + s/^\s*//; + s/\s*$//; + next unless /\S/; + $order{$_} = $count++; + } + close F; + # Overrides from config file + foreach my $xbus (@xbuses) { + my $label = $xbus->label; + my $val; + $val = $order{$label}; + $val = $order{$xbus->connector} unless defined $val; + $xbus->{XPPORDER} = $val if defined $val; + } +} + +sub xbuses { + my $optsort = shift || 'SORT_XPPORDER'; + my @sorted_xbuses; + + if(! @xbuses) { + @xbuses = Dahdi::Xpp->scan(); + } + add_xpporder(@xbuses); + my $sorter = sorters($optsort); + die "Unknown optional sorter '$optsort'" unless defined $sorter; + @sorted_xbuses = sort $sorter @xbuses; + return @sorted_xbuses; +} + +sub xpd_of_span($) { + my $span = shift or die "Missing span parameter"; + return undef unless defined $span; + foreach my $xbus (Dahdi::Xpp::xbuses) { + foreach my $xpd ($xbus->xpds()) { + return $xpd if $xpd->fqn eq $span->name; + } + } + return undef; +} + +=head1 sync([new_sync_source]) + +Gets (and optionally sets) the internal Astribanks synchronization +source. When used to set sync source, returns the original sync source. + +A synchronization source is a value valid writing into + /sys/bus/astribanks/drivers/xppdrv/sync +For more information read that file and see README.Astribank . + +=cut + +sub sync { + my ($newsync) = @_; + my $result; + my $file = "$sysfs_ab_driver/sync"; + die "Missing '$file'\n" unless -f $file; + open(F, "$file") or die "Failed to open $file for reading: $!"; + $result = ; + close F; + chomp $result; + $result =~ s/^SYNC=\D*//; + if(defined $newsync) { # Now change + $newsync =~ s/.*/\U$&/; + if($newsync =~ /^(\d+)$/) { + $newsync = "SYNC=$1"; + } elsif($newsync ne 'DAHDI') { + die "Bad sync parameter '$newsync'"; + } + open(F, ">$file") or die "Failed to open $file for writing: $!"; + print F $newsync; + close(F) or die "Failed in closing $file: $!"; + } + return $result; +} + +=head1 SEE ALSO + +=over + +=item L + +Xbus (Astribank) object. + +=item L + +XPD (the rough equivalent of a Dahdi span) object. + +=item L + +Object for a line: an analog port or a time-slot in a adapter. +Equivalent of a channel in Dahdi. + +=item L + +General documentation in the master package. + +=back + +=cut + +1; diff --git a/xpp/perl_modules/Dahdi/Xpp/Line.pm b/xpp/perl_modules/Dahdi/Xpp/Line.pm new file mode 100644 index 0000000..bb0ec27 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Xpp/Line.pm @@ -0,0 +1,65 @@ +package Dahdi::Xpp::Line; +# +# Written by Oron Peled +# Copyright (C) 2008, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use Dahdi::Utils; + +sub new($$$) { + my $pack = shift or die "Wasn't called as a class method\n"; + my $xpd = shift or die; + my $index = shift; + defined $index or die; + my $self = {}; + bless $self, $pack; + $self->{XPD} = $xpd; + $self->{INDEX} = $index; + return $self; +} + +sub blink($$) { + my $self = shift; + my $on = shift; + my $xpd = $self->xpd; + my $result = $xpd->xpd_getattr("blink"); + $result = hex($result); + if(defined($on)) { # Now change + my $onbitmask = 1 << $self->index; + my $offbitmask = $result & ~$onbitmask; + + $result = $offbitmask; + $result |= $onbitmask if $on; + $result = $xpd->xpd_setattr("blink", $result); + } + return $result; +} + +sub create_all($$) { + my $pack = shift or die "Wasn't called as a class method\n"; + my $xpd = shift || die; + local $/ = "\n"; + my @lines; + for(my $i = 0; $i < $xpd->{CHANNELS}; $i++) { + my $line = Dahdi::Xpp::Line->new($xpd, $i); + push(@lines, $line); + } + $xpd->{LINES} = \@lines; + if($xpd->type eq 'FXO') { + my $battery = $xpd->xpd_getattr("fxo_battery"); + die "Missing '$battery' attribute\n" unless defined $battery; + my @batt = split(/\s+/, $battery); + foreach my $l (@lines) { + die unless @batt; + my $state = shift @batt; + $l->{BATTERY} = ($state eq '+') ? 1 : 0; + } + } +} + + +1; diff --git a/xpp/perl_modules/Dahdi/Xpp/Mpp.pm b/xpp/perl_modules/Dahdi/Xpp/Mpp.pm new file mode 100644 index 0000000..2c11a94 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Xpp/Mpp.pm @@ -0,0 +1,222 @@ +package Dahdi::Xpp::Mpp; +# +# Written by Oron Peled +# Copyright (C) 2009, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use File::Basename; +use Getopt::Std; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); } + +use Dahdi::Utils; + +=head1 NAME + +Dahdi::Xpp::Mpp - Perl interface to C + +=head1 DESCRIPTION + +This package uses C to collect information +about Astribanks via MPP (Management Processor Protocol). + +The binary default location is F. It may be +overridden via module parameter C and the +C environment variable (higher priority). + +It may also be set/unset from code via the set_astribank_tool() method. + +=head1 METHODS + +=head2 mpp_addinfo() + +Called with a list of C objects and augment their +data with C objects. + +This method is the normal external interface of this class. + +=head2 new() + +Constructor. Receive as parameter an instance of C class +and return a C object. + +Normally, used indirectly via the mpp_addinfo() method. + +=head2 set_astribank_tool() + +Override default location of astribank_tool(8). It is legal +to set it to C. + +=head2 showinfo() + +Dump an C object for debugging. + +=cut + +my $astribank_tool = '/usr/sbin/astribank_tool'; + +sub set_astribank_tool($$) { + my $pack = shift || die; + $pack eq 'Dahdi::Xpp::Mpp' or die "$0: Called from wrong package? ($pack)"; + my $arg = shift; + $astribank_tool = $arg; + #print STDERR "Setting astribank_tool='$astribank_tool'\n"; +} + +sub import { + my ($param) = grep(/^astribank_tool=/, @_); + if(defined $param) { + $param =~ s/^astribank_tool=//; + $astribank_tool = $param; + } + if(defined $ENV{ASTRIBANK_TOOL}) { + $astribank_tool = $ENV{ASTRIBANK_TOOL}; + } +} + +sub showinfo($$) { + my $self = shift || die; + my $prefix = shift || die; + + return unless defined $self; + foreach my $k (sort keys %{$self}) { + my $v = $self->{$k}; + if(ref($v) eq 'ARRAY') { + my @a = @{$v}; + my $i; + my $ki; + for($i = 0; $i < @a; $i++) { + $ki = sprintf "%s[%d]", $k, $i; + printf "$prefix%-20s %s\n", $ki, $a[$i]; + } + } else { + if($k eq 'DEV') { + printf "$prefix%-20s -> %s\n", $k, $v->hardware_name; + } else { + printf "$prefix%-20s %s\n", $k, $v; + } + } + } +} + +sub astribank_tool_cmd($@) { + my $dev = shift || die; + my @args = @_; + my $usb_top; + + # Find USB bus toplevel + $usb_top = '/dev/bus/usb'; + $usb_top = '/proc/bus/usb' unless -d $usb_top; + die "No USB toplevel found\n" unless -d $usb_top; + my $name = $dev->priv_device_name(); + die "$0: Unkown private device name" unless defined $name; + my $path = "$usb_top/$name"; + return ($astribank_tool, '-D', "$path", @args); +} + +sub new($$$) { + my $pack = shift || die; + my $dev = shift || die; + my $product = $dev->product; + + return undef unless $dev->is_astribank; + return undef unless $dev->bus_type eq 'USB'; + return undef unless $product =~ /116./; + my $mppinfo = { + DEV => $dev, + HAS_MPP => 1, + }; + bless $mppinfo, $pack; + #print STDERR "$astribank_tool($path) -- '$product'\n"; + if(! -x $astribank_tool) { + warn "Could not run '$astribank_tool'\n"; + return $mppinfo; + } + return $mppinfo unless $product =~ /116[12]/; + $mppinfo->{'MPP_TALK'} = 1; + my @cmd = astribank_tool_cmd($dev, '-Q'); + my $name = $dev->priv_device_name(); + my $dbg_file = "$name"; + $dbg_file =~ s/\W/_/g; + #$dbg_file = "/tmp/twinstar-debug-$dbg_file"; + $dbg_file = "/dev/null"; + unless(open(F, "@cmd 2> '$dbg_file' |")) { + warn "Failed running '$astribank_tool': $!"; + return undef; + } + local $/ = "\n"; + local $_; + while() { + chomp; + #printf STDERR "'%s'\n", $_; + if(s/^INFO:\s*//) { + $mppinfo->{'PROTOCOL'} = $1 if /^protocol\s+version:\s*(\d+)/i; + } elsif(s/^EEPROM:\s*//) { + $mppinfo->{'EEPROM_RELEASE'} = $1 if /^release\s*:\s*([\d\.]+)/i; + $mppinfo->{'EEPROM_LABEL'} = $1 if /^label\s*:\s*([\w._'-]+)/i; + } elsif(s/^Extrainfo:\s+:\s*(.+?)$//) { + $mppinfo->{'EEPROM_EXTRAINFO'} = $1; + } elsif(s/^Capabilities:\s*TwinStar\s*:\s*(.+?)$//) { + my $cap = $1; + $mppinfo->{'TWINSTAR_CAPABLE'} = ($cap =~ /yes/i) ? 1 : 0; + } elsif(s/^TwinStar:\s*//) { + $mppinfo->{'TWINSTAR_PORT'} = $1 if /^connected\s+to\s*:\s*usb-(\d+)/i; + if(s/^USB-(\d+)\s*POWER\s*:\s*//) { + my $v = ($_ eq 'ON') ? 1 : 0; + $mppinfo->{'TWINSTAR_POWER'}->[$1] = $v; + } + if(s/^Watchdog[^:]+:\s*//) { + my $v = ($_ eq 'on-guard') ? 1 : 0; + $mppinfo->{'TWINSTAR_WATCHDOG'} = $v; + } + #printf STDERR "\t%s\n", $_; + } else { + #printf STDERR "\t%s\n", $_; + } + } + unless(close F) { + warn "Failed running '$astribank_tool': $!"; + return undef; + } + #$mppinfo->showinfo; + return $mppinfo; +} + +sub mpp_setwatchdog($$) { + my $mppinfo = shift || die; + my $on = shift; + die "$0: Bad value '$on'" unless defined($on) && $on =~ /^[0-1]$/; + my $dev = $mppinfo->dev || die; + return undef unless defined $mppinfo->mpp_talk; + my $old = $mppinfo->tws_watchdog; + my @cmd = astribank_tool_cmd($dev, '-w', $on); + print STDERR "DEBUG($on): '@cmd'\n"; + system(@cmd); + die "Running $astribank_tool failed: $?" if $?; +} + +sub mpp_jump($) { + my $mppinfo = shift || die; + my $dev = $mppinfo->dev || die; + return undef unless defined $mppinfo->mpp_talk; + my $port = $mppinfo->twinstar_port; + $port = ($port == 1) ? 0 : 1; + die "Unknown TwinStar port" unless defined $port; + my @cmd = astribank_tool_cmd($dev, '-p', $port); + system(@cmd); + die "Running $astribank_tool failed: $?" if $?; +} + +sub mpp_addinfo($@) { + my $pack = shift || die; + my @devlist = @_; + + foreach my $dev (@devlist) { + $dev->{MPPINFO} = $pack->new($dev); + } +} + +1; diff --git a/xpp/perl_modules/Dahdi/Xpp/Xbus.pm b/xpp/perl_modules/Dahdi/Xpp/Xbus.pm new file mode 100644 index 0000000..e1973b1 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Xpp/Xbus.pm @@ -0,0 +1,212 @@ +package Dahdi::Xpp::Xbus; +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use Dahdi::Utils; +use Dahdi::Hardware; +use Dahdi::Xpp::Xpd; + +sub xpds($) { + my $xbus = shift; + return @{$xbus->{XPDS}}; +} + +sub by_number($) { + my $busnumber = shift; + die "Missing xbus number parameter" unless defined $busnumber; + my @xbuses = Dahdi::Xpp::xbuses(); + + my ($xbus) = grep { $_->num == $busnumber } @xbuses; + return $xbus; +} + +sub by_label($) { + my $label = shift; + die "Missing xbus label parameter" unless defined $label; + my @xbuses = Dahdi::Xpp::xbuses(); + + my ($xbus) = grep { $_->label eq $label } @xbuses; + return $xbus; +} + +sub get_xpd_by_number($$) { + my $xbus = shift; + my $xpdid = shift; + die "Missing XPD id parameter" unless defined $xpdid; + $xpdid = sprintf("%02d", $xpdid); + my @xpds = $xbus->xpds; + my ($wanted) = grep { $_->id eq $xpdid } @xpds; + return $wanted; +} + +sub xbus_getattr($$) { + my $xbus = shift || die; + my $attr = shift || die; + $attr = lc($attr); + my $file = sprintf "%s/%s", $xbus->sysfs_dir, $attr; + + open(F, $file) || die "Failed opening '$file': $!"; + my $val = ; + close F; + chomp $val; + return $val; +} + +sub read_attrs() { + my $xbus = shift || die; + my @attrnames = qw(CONNECTOR LABEL STATUS); + my @attrs; + + foreach my $attr (@attrnames) { + my $val = xbus_getattr($xbus, $attr); + if($attr eq 'STATUS') { + # Some values are in all caps as well + $val = uc($val); + } elsif($attr eq 'CONNECTOR') { + $val =~ s/^/@/; # Add prefix + } elsif($attr eq 'LABEL') { + # Fix badly burned labels. + $val =~ s/[[:^print:]]/_/g; + } + $xbus->{$attr} = $val; + } +} + +sub transport_type($$) { + my $xbus = shift || die; + my $xbus_dir = shift; + my $transport = "$xbus_dir/transport"; + if(-e "$transport/ep_00") { # It's USB + $xbus->{TRANSPORT_TYPE} = 'USB'; + } else { + warn "Unkown transport in $xbus_dir\n"; + undef $xbus->{TRANSPORT_TYPE}; + } + return $xbus->{TRANSPORT_TYPE}; +} + +sub read_xpdnames($) { + my $xbus_dir = shift or die; + my $pat = sprintf "%s/[0-9][0-9]:[0-9]:[0-9]", $xbus_dir; + my @xpdnames; + + #printf STDERR "read_xpdnames(%s): $pat\n", $xbus_dir; + foreach (glob $pat) { + die "Bad /sys entry: '$_'" unless m/^.*\/([0-9][0-9]):([0-9]):([0-9])$/; + my ($busnum, $unit, $subunit) = ($1, $2, $3); + my $name = sprintf("%02d:%1d:%1d", $1, $2, $3); + #print STDERR "\t> $_ ($name)\n"; + push(@xpdnames, $name); + } + return @xpdnames; +} + +sub read_num($) { + my $self = shift or die; + my $xbus_dir = $self->sysfs_dir; + $xbus_dir =~ /.*-(\d\d)$/; + return $1; +} + +sub new($$) { + my $pack = shift or die "Wasn't called as a class method\n"; + my $parent_dir = shift or die; + my $entry_dir = shift or die; + my $xbus_dir = "$parent_dir/$entry_dir"; + my $self = {}; + bless $self, $pack; + $self->{SYSFS_DIR} = $xbus_dir; + my $num = $self->read_num; + $self->{NUM} = $num; + $self->{NAME} = "XBUS-$num"; + $self->read_attrs; + # Get transport related info + my $transport = "$xbus_dir/transport"; + die "OLD DRIVER: missing '$transport'\n" unless -e $transport; + my $transport_type = $self->transport_type($xbus_dir); + if(defined $transport_type) { + my $tt = "Dahdi::Hardware::$transport_type"; + my $hw = $tt->set_transport($self, $xbus_dir); + #printf STDERR "Xbus::new transport($transport_type): %s\n", $hw->{HARDWARE_NAME}; + } + my @xpdnames; + my @xpds; + @xpdnames = read_xpdnames($self->sysfs_dir); + foreach my $xpdstr (@xpdnames) { + my $xpd = Dahdi::Xpp::Xpd->new($self, $xpdstr); + push(@xpds, $xpd); + } + @{$self->{XPDS}} = sort { $a->id <=> $b->id } @xpds; + return $self; +} + +sub dahdi_registration($$) { + my $xbus = shift; + my $on = shift; + my $result; + my $file = sprintf("%s/dahdi_registration", $xbus->sysfs_dir); + # Handle old drivers without dahdi_registration xbus attribute + if (! -f $file) { + warn "Old xpp driver without dahdi_registration support. Emulating it using xpd/span support\n"; + my @xpds = sort { $a->id <=> $b->id } $xbus->xpds(); + my $prev; + foreach my $xpd (@xpds) { + $prev = $xpd->dahdi_registration($on); + } + return $prev; + } + # First query + open(F, "$file") or die "Failed to open $file for reading: $!"; + $result = ; + chomp $result; + close F; + if(defined($on) and $on ne $result) { # Now change + open(F, ">$file") or die "Failed to open $file for writing: $!"; + print F ($on)?"1":"0"; + if(!close(F)) { + if($! == 17) { # EEXISTS + # good + } else { + undef $result; + } + } + } + return $result; +} + +sub pretty_xpds($) { + my $xbus = shift; + my @xpds = sort { $a->id <=> $b->id } $xbus->xpds(); + my @xpd_types = map { $_->type } @xpds; + my $last_type = ''; + my $mult = 0; + my $xpdstr = ''; + foreach my $curr (@xpd_types) { + if(!$last_type || ($curr eq $last_type)) { + $mult++; + } else { + if($mult == 1) { + $xpdstr .= "$last_type "; + } elsif($mult) { + $xpdstr .= "$last_type*$mult "; + } + $mult = 1; + } + $last_type = $curr; + } + if($mult == 1) { + $xpdstr .= "$last_type "; + } elsif($mult) { + $xpdstr .= "$last_type*$mult "; + } + $xpdstr =~ s/\s*$//; # trim trailing space + return $xpdstr; +} + +1; diff --git a/xpp/perl_modules/Dahdi/Xpp/Xpd.pm b/xpp/perl_modules/Dahdi/Xpp/Xpd.pm new file mode 100644 index 0000000..810ad9e --- /dev/null +++ b/xpp/perl_modules/Dahdi/Xpp/Xpd.pm @@ -0,0 +1,332 @@ +package Dahdi::Xpp::Xpd; +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use Dahdi::Utils; +use Dahdi::Xpp; +use Dahdi::Xpp::Line; + +=head1 NAME + +Dahdi::Xpp::Xpd - Perl interface to the Xorcom Astribank XPDs (spans) + +=head1 SYNOPSIS + + # Listing all Astribanks: + use Dahdi::Xpp; + # scans hardware: + my @xbuses = Dahdi::Xpp::xbuses("SORT_CONNECTOR"); + for my $xbus (@xbuses) { + print $xbus->name." (".$xbus->label .", ". $xbus->connector .")\n"; + for my $xpd ($xbus->xpds) { + print " - ".$xpd->fqn,"\n"; + } + } + +=head1 xbus + +The parent L + +=head1 id + +The two-digit ID in the Xbus. Normally 0I for digital spans and +I0 for analog ones (for some digit, I). + +=head1 unit + +First digit of the ID. Zero-based number of the module inside the +Astribank, + +=head1 subunit + +Second digit of the ID. Zero-based sub-part inside the module. +Applicable only to digital (BRI/PRI) modules and always 0 for others. + +=head1 FQN + +Textual name: E.g. C. + +=head1 sysfs_dir + +The SysFS directory with information about the module. E.g. +C. + +=head1 channels + +A list of L channels of this span. In a scalar context +this will be the number of channels in the span. + +=head1 spanno + +0 if not registered with Dahdi. Otherwise, the number of the span it is +registered as. + +=head1 type + +The type of the XPD. One of: C, C, C, C, +C, C. + +=head1 is_bri + +True if this XPD is BRI. + +=head1 is_pri + +True if this XPD is PRI (E1/T1). + +=head1 is_digital + +True if this XPD is a digital port (BRI / PRI). + +=head1 termtype + +For a digital span: C or C. + +=head1 dchan_hardhdlc + +For a BRI port: true if the driver with hardhdlc support (rather than +bri_dchan). + +=cut + +my %file_warned; # Prevent duplicate warnings about same file. + +sub xpd_attr_path($@) { + my $self = shift || die; + my $xbus = $self->xbus; + my ($busnum, $unitnum, $subunitnum, @attr) = ( + $xbus->num, + $self->unit, + $self->subunit, + @_); + foreach my $attr (@attr) { + my $file = sprintf "%s/%02d:%1d:%1d/$attr", + $xbus->sysfs_dir, $busnum, $unitnum, $subunitnum; + next unless -f $file; + return $file; + } + return undef; +} + +my %attr_missing_warned; # Prevent duplicate warnings + +sub xpd_driver_getattr($$) { + my $xpd = shift || die; + my $attr = shift || die; + $attr = lc($attr); + my ($busnum, $unitnum, $subunitnum) = ($xpd->xbus->num, $xpd->unit, $xpd->subunit); + my $file = sprintf "$Dahdi::Xpp::sysfs_xpds/%02d:%1d:%1d/driver/$attr", + $busnum, $unitnum, $subunitnum; + if(!defined($file)) { + warn "$0: xpd_driver_getattr($attr) -- Missing attribute.\n" if + $attr_missing_warned{$attr}; + return undef; + } + open(F, $file) || return undef; + my $val = ; + close F; + chomp $val; + return $val; +} + +sub xpd_getattr($$) { + my $xpd = shift || die; + my $attr = shift || die; + $attr = lc($attr); + my $file = $xpd->xpd_attr_path(lc($attr)); + + if(!defined($file)) { + warn "$0: xpd_getattr($attr) -- Missing attribute.\n" if + $attr_missing_warned{$attr}; + return undef; + } + open(F, $file) || return undef; + my $val = ; + close F; + chomp $val; + return $val; +} + +sub xpd_setattr($$$) { + my $xpd = shift || die; + my $attr = shift || die; + my $val = shift; + $attr = lc($attr); + my $file = xpd_attr_path($xpd, $attr); + my $oldval = $xpd->xpd_getattr($attr); + open(F, ">$file") or die "Failed to open $file for writing: $!"; + print F "$val"; + if(!close(F)) { + if($! == 17) { # EEXISTS + # good + } else { + return undef; + } + } + return $oldval; +} + +sub blink($$) { + my $self = shift; + my $on = shift; + my $result = $self->xpd_getattr("blink"); + if(defined($on)) { # Now change + $self->xpd_setattr("blink", ($on)?"0xFFFF":"0"); + } + return $result; +} + +sub dahdi_registration($$) { + my $self = shift; + my $on = shift; + my $result; + my $file = $self->xpd_attr_path("span", "dahdi_registration"); + die "$file is missing" unless -f $file; + # First query + open(F, "$file") or die "Failed to open $file for reading: $!"; + $result = ; + chomp $result; + close F; + if(defined($on) and $on ne $result) { # Now change + open(F, ">$file") or die "Failed to open $file for writing: $!"; + print F ($on)?"1":"0"; + if(!close(F)) { + if($! == 17) { # EEXISTS + # good + } else { + undef $result; + } + } + } + return $result; +} + +sub xpds_by_spanno() { + my @xbuses = Dahdi::Xpp::xbuses(); + my @xpds = map { $_->xpds } @xbuses; + @xpds = grep { $_->spanno } @xpds; + @xpds = sort { $a->spanno <=> $b->spanno } @xpds; + my @spanno = map { $_->spanno } @xpds; + my @idx; + @idx[@spanno] = @xpds; # The spanno is the index now + return @idx; +} + +sub new($$$) { + my $pack = shift or die "Wasn't called as a class method\n"; + my $xbus = shift or die; + my $xpdstr = shift or die; + my $sysfsdir = sprintf "%s/%s", $xbus->sysfs_dir, $xpdstr; + my ($busnum, $unit, $subunit) = split(/:/, $xpdstr); + my $self = { + XBUS => $xbus, + ID => sprintf("%1d%1d", $unit, $subunit), + FQN => $xbus->name . "/" . "XPD-$unit$subunit", + UNIT => $unit, + SUBUNIT => $subunit, + SYSFS_DIR => $sysfsdir, + }; + bless $self, $pack; + my @offhook = split / /, ($self->xpd_getattr('offhook')); + $self->{CHANNELS} = @offhook; + my $type = $self->xpd_getattr('type'); + my $span = $self->xpd_getattr('span'); + my $timing_priority = $self->xpd_getattr('timing_priority'); + $self->{SPANNO} = $span; + $self->{TYPE} = $type; + $self->{TIMING_PRIORITY} = $timing_priority; + if($type =~ /BRI_(NT|TE)/) { + $self->{IS_BRI} = 1; + $self->{TERMTYPE} = $1; + $self->{DCHAN_HARDHDLC} = $self->xpd_driver_getattr('dchan_hardhdlc'); + } elsif($type =~ /[ETJ]1/) { + $self->{IS_PRI} = 1; + # older drivers may not have 'timing_priority' + # attribute. Preserve original behaviour: + if(defined($timing_priority) && ($timing_priority == 0)) { + $self->{TERMTYPE} = 'NT'; + } else { + $self->{TERMTYPE} = 'TE'; + } + } + $self->{IS_DIGITAL} = ( $self->{IS_BRI} || $self->{IS_PRI} ); + Dahdi::Xpp::Line->create_all($self); + return $self; +} + +#------------------------------------ +# static xpd related helper functions +#------------------------------------ + +# Returns only the telephony XPD's from a list +# of one or more XPD's. +# I.e: Filters-out ECHO cancelers +sub telephony_devs { + my @devs = grep { $_->channels } @_; + return @devs; +} + +sub format_rank($$) { + my ($rank, $prio) = @_; + my $width = 2; + # 0 is replaced with a character that is sorted *AFTER* numbers. + $prio = '_' x $width unless defined $prio && $prio; + return sprintf "%${width}s-%s", $prio, $rank; +} + +sub sync_priority_rank($) { + my $xpd = shift || die; + my $prio = $xpd->timing_priority; + # The @rank array is ordered by priority of sync (good to bad) + # It is used when timing_priority is not defined (analog) or + # is 0 (NT). + my @rank = ( + ($xpd->is_pri and defined($xpd->termtype) and $xpd->termtype eq 'TE'), + ($xpd->is_bri and defined($xpd->termtype) and $xpd->termtype eq 'TE'), + ($xpd->type eq 'FXO'), + ($xpd->is_pri), + ($xpd->is_bri), + ($xpd->type eq 'FXS'), + ); + my $i; + for($i = 0; $i < @rank; $i++) { + last if $rank[$i]; + } + return format_rank($i, $prio); +} + +# An XPD sync priority comparator for sort() +sub sync_priority_compare() { + my $rank_a = sync_priority_rank($a); + my $rank_b = sync_priority_rank($b); + #print STDERR "DEBUG(rank): $rank_a (", $a->fqn, ") $rank_b (", $b->fqn, ")\n"; + return $rank_a cmp $rank_b; # The easy case +} + +# For debugging: show a list of XPD's with relevant sync info. +sub show_xpd_rank(@) { + print STDERR "XPD's by rank\n"; + foreach my $xpd (@_) { + my $type = $xpd->type; + my $extra = ""; + my $rank = sync_priority_rank($xpd); + if($xpd->is_digital) { + $extra .= " termtype " . ($xpd->termtype || "UNKNOWN"); + } + printf STDERR "%3s %-15s %s\n", $rank, $xpd->fqn, $extra; + } +} + +sub xpds_by_rank(@) { + my @xpd_prio = sort sync_priority_compare @_; + #show_xpd_rank(@xpd_prio); + return @xpd_prio; +} + +1; diff --git a/xpp/pic_loader.c b/xpp/pic_loader.c new file mode 100644 index 0000000..c6ed3f1 --- /dev/null +++ b/xpp/pic_loader.c @@ -0,0 +1,285 @@ +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include "hexfile.h" +#include "pic_loader.h" +#include +#include + +#define DBG_MASK 0x03 +#define MAX_HEX_LINES 10000 +#define TIMEOUT 500 + +enum xpp_packet_types { + PIC_REQ_XOP = 0x09, + PIC_REP_XOP = 0x0A +}; + +struct xpp_packet_header { + struct { + uint16_t len; + uint8_t op; + uint8_t unit; + } PACKED header; + union { + struct { + struct { + uint8_t flags; + uint8_t card_type; + uint16_t offs; + } pic_header; + uint8_t data[3]; + } PACKED pic_packet; + } d; +} PACKED; + +int send_picline(struct astribank_device *astribank, uint8_t card_type, enum pic_command pcmd, int offs, uint8_t *data, int data_len) +{ + int recv_answer = 0; + char buf[PACKET_SIZE]; + struct xpp_packet_header *phead = (struct xpp_packet_header *)buf; + int pack_len; + int ret; + + assert(astribank != NULL); + pack_len = data_len + sizeof(phead->header) + sizeof(phead->d.pic_packet.pic_header); + phead->header.len = pack_len; + phead->header.op = PIC_REQ_XOP; + phead->header.unit = 0x00; + phead->d.pic_packet.pic_header.flags = pcmd; + phead->d.pic_packet.pic_header.card_type = card_type; + phead->d.pic_packet.pic_header.offs = offs; + if(data) + memcpy(phead->d.pic_packet.data, data, data_len); + switch (pcmd) { + case PIC_START_FLAG: + break; + case PIC_DATA_FLAG: + break; + case PIC_END_FLAG: + recv_answer = 1; + break; + case PIC_ENDS_FLAG: + break; + } + + DBG("PICLINE: pack_len=%d pcmd=%d\n", pack_len, pcmd); + dump_packet(LOG_DEBUG, DBG_MASK, "dump:picline[W]", (char *)phead, pack_len); + + ret = xusb_send(astribank->xusb, buf, pack_len, TIMEOUT); + if(ret < 0) { + ERR("xusb_send failed: %d\n", ret); + return ret; + } + DBG("xusb_send: Written %d bytes\n", ret); + if (recv_answer) { + ret = xusb_recv(astribank->xusb, buf, sizeof(buf), TIMEOUT); + if(ret <= 0) { + ERR("No USB packs to read\n"); + return ret; + } else { + phead = (struct xpp_packet_header *)buf; + if(phead->header.op != PIC_REP_XOP) { + ERR("Got unexpected reply OP=0x%02X\n", phead->header.op); + dump_packet(LOG_ERR, DBG_MASK, "hexline[ERR]", buf, ret); + return -EINVAL; + } + DBG("received OP=0x%02X, checksum=%02X\n", phead->header.op, phead->d.pic_packet.data[0]); + if(phead->d.pic_packet.data[0] != 0) { + ERR("PIC burning, bad checksum\n"); + return -EINVAL; + } + } + } + return 0; +} + +static const char *pic_basename(const char *fname, uint8_t *card_type) +{ + const char *basename; + regex_t regex; + char ebuf[BUFSIZ]; + const char re[] = "PIC_TYPE_([0-9]+)\\.hex"; + regmatch_t pmatch[2]; /* One for the whole match, one for the number */ + int nmatch = (sizeof(pmatch)/sizeof(pmatch[0])); + int len; + int ret; + + basename = strrchr(fname, '/'); + if(!basename) + basename = fname; + if((ret = regcomp(®ex, re, REG_ICASE | REG_EXTENDED)) != 0) { + regerror(ret, ®ex, ebuf, sizeof(ebuf)); + ERR("regcomp: %s\n", ebuf); + return NULL; + } + if((ret = regexec(®ex, basename, nmatch, pmatch, 0)) != 0) { + regerror(ret, ®ex, ebuf, sizeof(ebuf)); + ERR("regexec: %s\n", ebuf); + regfree(®ex); + return NULL; + } + /* + * Should have both complete match and a parentheses match + */ + if(pmatch[0].rm_so == -1 || pmatch[1].rm_so == -1) { + ERR("pic_basename: Bad match: pmatch[0].rm_so=%d pmatch[1].rm_so=%d\n", + pmatch[0].rm_so, pmatch[1].rm_so == -1); + regfree(®ex); + return NULL; + } + len = pmatch[1].rm_eo - pmatch[1].rm_so; + if(len >= sizeof(ebuf) - 1) + len = sizeof(ebuf) - 1; + memcpy(ebuf, basename + pmatch[1].rm_so, len); + ebuf[len] = '\0'; + DBG("match: %s\n", ebuf); + ret = atoi(ebuf); + if(ret <= 0 || ret > 9) { + ERR("pic_basename: Bad type number %d\n", ret); + regfree(®ex); + return NULL; + } + *card_type = ret; + regfree(®ex); + return basename; +} + +/* + * Returns: true on success, false on failure + */ +static int pic_burn(struct astribank_device *astribank, const struct hexdata *hexdata) +{ + const char *v = hexdata->version_info; + const char *basename; + uint8_t *data; + unsigned char check_sum = 0; + uint8_t card_type; + int ret; + unsigned int i; + const char *devstr; + + v = (v[0]) ? v : "Unknown"; + assert(astribank != NULL); + assert(hexdata != NULL); + devstr = xusb_devpath(astribank->xusb); + if(!astribank->is_usb2) { + ERR("%s: Skip PIC burning (not USB2)\n", devstr); + return 0; + } + INFO("%s [%s]: Loading PIC Firmware: %s (version %s)\n", + devstr, + xusb_serial(astribank->xusb), + hexdata->fname, + hexdata->version_info); + basename = pic_basename(hexdata->fname, &card_type); + if(!basename) { + ERR("%s: Bad PIC filename '%s'. Abort.\n", devstr, hexdata->fname); + return 0; + } + DBG("basename=%s card_type=%d maxlines=%d\n", + basename, card_type, hexdata->maxlines); + /* + * Try to read extra left-overs from USB controller + */ + for(i = 2; i; i--) { + char buf[PACKET_SIZE]; + + if(xusb_recv(astribank->xusb, buf, sizeof(buf), 1) <= 0) + break; + } + if((ret = send_picline(astribank, card_type, PIC_START_FLAG, 0, NULL, 0)) != 0) { + perror("Failed sending start hexline"); + return 0; + } + for(i = 0; i < hexdata->maxlines; i++) { + struct hexline *hexline; + unsigned int len; + + hexline = hexdata->lines[i]; + if(!hexline) { + ERR("%s: hexdata finished early (line %d)", devstr, i); + return 0; + } + if(hexline->d.content.header.tt == TT_DATA) { + len = hexline->d.content.header.ll; /* don't send checksum */ + if(len != 3) { + ERR("%s: Bad line len %d\n", devstr, len); + return 0; + } + data = hexline->d.content.tt_data.data; + check_sum ^= data[0] ^ data[1] ^ data[2]; + ret = send_picline(astribank, card_type, PIC_DATA_FLAG, + hexline->d.content.header.offset, data, len); + if(ret) { + perror("Failed sending data hexline"); + return 0; + } + } else if(hexline->d.content.header.tt == TT_EOF) { + break; + } else { + ERR("%s: Unexpected TT = %d in line %d\n", + devstr, hexline->d.content.header.tt, i); + return 0; + } + } + if((ret = send_picline(astribank, card_type, PIC_END_FLAG, 0, &check_sum, 1)) != 0) { + perror("Failed sending end hexline"); + return 0; + } + DBG("Finished...\n"); + return 1; +} + +int load_pic(struct astribank_device *astribank, int numfiles, char *filelist[]) +{ + int i; + const char *devstr; + + devstr = xusb_devpath(astribank->xusb); + DBG("%s: Loading %d PIC files...\n", devstr, numfiles); + for(i = 0; i < numfiles; i++) { + struct hexdata *picdata; + const char *curr = filelist[i]; + + DBG("%s\n", curr); + if((picdata = parse_hexfile(curr, MAX_HEX_LINES)) == NULL) { + perror(curr); + return -errno; + } + if(!pic_burn(astribank, picdata)) { + ERR("%s: PIC %s burning failed\n", devstr, curr); + return -ENODEV; + } + free_hexdata(picdata); + } + if((i = send_picline(astribank, 0, PIC_ENDS_FLAG, 0, NULL, 0)) != 0) { + ERR("%s: PIC end burning failed\n", devstr); + return -ENODEV; + } + return 0; +} diff --git a/xpp/pic_loader.h b/xpp/pic_loader.h new file mode 100644 index 0000000..f871bca --- /dev/null +++ b/xpp/pic_loader.h @@ -0,0 +1,46 @@ +#ifndef PIC_LOADER_H +#define PIC_LOADER_H +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include "astribank_usb.h" + +/* + * Astribank PIC loading + */ + +enum pic_command { + PIC_DATA_FLAG = 0x00, + PIC_START_FLAG = 0x01, + PIC_END_FLAG = 0x02, + PIC_ENDS_FLAG = 0x04, +}; + +#define PIC_PACK_LEN 0x0B +#define PIC_LINE_LEN 0x03 + +int send_picline(struct astribank_device *astribank, uint8_t card_type, + enum pic_command pcmd, int offs, uint8_t *data, int data_len); +int load_pic(struct astribank_device *astribank, int numfiles, char *filelist[]); + +#endif /* PIC_LOADER_H */ diff --git a/xpp/test_parse.c b/xpp/test_parse.c new file mode 100644 index 0000000..4ae1038 --- /dev/null +++ b/xpp/test_parse.c @@ -0,0 +1,57 @@ +/* + * Written by Oron Peled + * Copyright (C) 2006, 2007, 2008, 2009 Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include "hexfile.h" + +static void default_report_func(int level, const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + vfprintf(stderr, msg, ap); + va_end(ap); +} + +int main(int argc, char *argv[]) +{ + struct hexdata *hd; + int i; + + if(argc < 2) { + fprintf(stderr, "Usage: program hexfile...\n"); + return 1; + } + parse_hexfile_set_reporting(default_report_func); + for(i = 1; i < argc; i++) { + hd = parse_hexfile(argv[i], 2000); + if(!hd) { + fprintf(stderr, "Parsing failed\n"); + return 1; + } + fprintf(stderr, "=== %s === (version: %s)\n", argv[i], hd->version_info); + dump_hexfile2(hd, "-", 60 ); + free_hexdata(hd); + } + return 0; +} diff --git a/xpp/twinstar b/xpp/twinstar new file mode 100755 index 0000000..287c9ef --- /dev/null +++ b/xpp/twinstar @@ -0,0 +1,267 @@ +#! /usr/bin/perl -w +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use File::Basename; +use Getopt::Std; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); } + +use Dahdi; +use Dahdi::Hardware; +use Dahdi::Span; +use Dahdi::Xpp; +use Dahdi::Xpp::Xbus; +use Dahdi::Xpp::Mpp; + +$Getopt::Std::STANDARD_HELP_VERSION = 1; +$main::VERSION = '$Id$'; + +sub HELP_MESSAGE() { + eval(usage()); + return 0; +} + +sub usage { + die "Usage: $0 {status|jump|enable-wd|disable-wd|ports}\n"; +} + +our ($opt_v, $opt_x); +getopts('vx') || usage; +@ARGV == 1 or usage; + + +# Find USB bus toplevel +my $usb_top; +$usb_top = '/dev/bus/usb'; +$usb_top = '/proc/bus/usb' unless -d $usb_top; +die "No USB toplevel found\n" unless -d $usb_top; + +sub tws_devs() { + my @devs; + foreach my $dev (Dahdi::Hardware->device_list) { + next unless $dev->is_astribank; + next unless $dev->product =~ /116./; + push(@devs, $dev->hardware_name); + } + return @devs; +} + +sub tws_usb_devfile($) { + my $name = shift || die; + # Remove prefix + if($name !~ s/usb://) { + die "$name is not a USB name\n"; + } + return "$usb_top/$name"; +} + +sub tws_show(@) { + my @usb_devs = @_; + my $format = "%-15s %-10s %-15s %-10s %-10s\n"; + + printf $format, 'DEVICE', 'PORT', 'WATCHDOG', 'POWER0', 'POWER1'; + foreach my $dev (@usb_devs) { + my $mppinfo = $dev->mppinfo; + if(!defined $mppinfo) { + printf STDERR "%s: no MPP information\n", $dev->hardware_name; + next; + } + if(!defined $mppinfo->{TWINSTAR_PORT}) { + printf STDERR "%s: no TWINSTAR_PORT information\n", $dev->hardware_name; + next; + } + my $power = $mppinfo->twinstar_power; + printf $format, + $dev->hardware_name, + $mppinfo->twinstar_port, + ($mppinfo->twinstar_watchdog) ? "on" : "off", + ($power->[0]) ? "yes" : "no", + ($power->[1]) ? "yes" : "no"; + } +} + +sub tws_portnum($) { + my $dev = shift || die "Missing dev"; + my $mppinfo = $dev->mppinfo; + if(!defined $mppinfo) { + printf STDERR "%s: no MPP information\n", $dev->hardware_name; + return undef; + } + return $mppinfo->twinstar_port; +} + +sub tws_showports(@) { + my @usb_devs = @_; + foreach my $dev (@usb_devs) { + my $mppinfo = $dev->mppinfo; + if(!defined $mppinfo) { + printf STDERR "%s: no MPP information\n", $dev->hardware_name; + next; + } + if(!defined $mppinfo->{TWINSTAR_PORT}) { + printf STDERR "%s: no TWINSTAR_PORT information\n", $dev->hardware_name; + next; + } + printf "%s\n", $mppinfo->{TWINSTAR_PORT}; + } +} + +sub tws_watchdog($@) { + my $on = shift; + die "tws_watchdog() on/off?" unless defined $on; + my @usb_devs = @_; + + foreach my $dev (@usb_devs) { + my $mppinfo = $dev->mppinfo; + if(!defined $mppinfo) { + printf STDERR "%s: no MPP information\n", $dev->hardware_name; + next; + } + $mppinfo->mpp_setwatchdog($on); + } +} + +sub tws_jump(@) { + my @usb_devs = @_; + + foreach my $dev (@usb_devs) { + my $mppinfo = $dev->mppinfo; + if(!defined $mppinfo) { + printf STDERR "%s: no MPP information\n", $dev->hardware_name; + next; + } + eval { + $mppinfo->mpp_jump; + }; + warn $@ if $@; + } +} + +sub dev_list() { + my @devs; + foreach my $dev (Dahdi::Hardware->device_list) { + next unless $dev->is_astribank; + next unless $dev->product =~ /116./; + Dahdi::Xpp::Mpp->mpp_addinfo($dev); + push(@devs, $dev); + } + return @devs; +} + +my @usb_devices = dev_list(); + +if($ARGV[0] eq 'status') { + tws_show(@usb_devices); +} elsif($ARGV[0] eq 'jump') { + tws_jump(@usb_devices); +} elsif($ARGV[0] eq 'disable-wd') { + tws_watchdog(0, @usb_devices); +} elsif($ARGV[0] eq 'enable-wd') { + tws_watchdog(1, @usb_devices); +} elsif($ARGV[0] eq 'ports') { + tws_showports(@usb_devices); +} else { + usage; +} + +__END__ + +=head1 NAME + +twinstar - Control the Twinstar feature of a Xorcom Astribank + +=head1 SYNOPSIS + +twinstar {status|jump|enable-wd|disable-wd|ports} + +=head1 DESCRIPTION + +B is a tool to control the Twinstar (dual USB port) of a +Xorcom Astribank. There is a single and mandatory argument which is the +command to run. That command operates on all the Astribanks connected to +the system. + +Technically all the commands are implemented using Dahdi::Xpp::Mpp which +in turn uses astribank_tool. Thus using thus tool will require root +permissions or otherwise read/write permissions to the USB device. + +The twinstar may be in I, which means that it will jump +to the remote host if it loses contact with the local host. This can +happen if the machine is powered down or hangs or even if the xpp +drivers are unloaded. Which is why the standard twinstar scripts put the +Astribanks in twinstar mode on startup and remove it on normal shutdown. + +An Astribank will only jump to the other host (either if asked +explicitly or by the watchdog) only if there is a different Astribank +connected to the other port and running. Which is why all of this has no +effect on systems that don't need this functionality. + +The command are: + +=head2 status + +Shows the current status of all Astribanks. Note that it only shows +Astribanks whose current active USB port is the one connected to this +computer. + +Example output: + + DEVICE PORT WATCHDOG POWER0 POWER1 + usb:001/010 0 on yes yes + usb:001/011 0 on yes yes + +For each Astribank on the system that has Twinstar support we get: + +=over 4 + +=item Device + +The address of the device. This is the bus address, e.g. the address you +see in lsusb / dahdi_hardware. + +=item Port + +The active USB port on the Astribank. This should be always '0' on the +master and always 1 on the slave. + +=item Watchdog + +I if the watchdog is triggered in the Atribank or I otherwise. + +=item Power0, Power1 + +Shows which ports of this Astribank are connected to a USB port of a +running computer. This only shows whether or not the USB host provides +power. + +=back + +=head2 ports + +Shows the same 'Port' column of the B command. + +=head2 jump + +Command all the Astribanks to jump to the other port. This works +regardless the watchdog mode is enabled or not. But requires that there +is power on the other port. + +=head2 enable-wd + +Enables watchdog mode. + +=head2 disable-wd + +Disables watchdog mode. + +=head1 FILES + +B mostly uses astribank_tool which in turn mostly uses USB +files under /dev/bus/usb . + diff --git a/xpp/twinstar_hook b/xpp/twinstar_hook new file mode 100755 index 0000000..712d572 --- /dev/null +++ b/xpp/twinstar_hook @@ -0,0 +1,86 @@ +#! /bin/sh +# +# twinstar_hook: Example twinstar-specific hook script +# $Id$ +# +# Written by Oron Peled +# Copyright (C) 2009, Xorcom +# +# All rights reserved. +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +# +# This is an experimental script to activate an Astribank TwinStar +# during failover. +# +# The script assume that there is an /etc/dahdi/xpp_order file +# specifying the Astribanks' labels according to the required +# registration order. +# +# This file can be easily generated by running: +# dahdi_genconf xpporder +# after the system is configured and working. +# + +me=`basename $0` +dir=`dirname $0` +LOGGER="logger -i -t '$me'" + +# Always redirect stderr somewhere, otherwise the shell script will die +# when it tries to do I/O related stuff on closed file descriptor. +# Our default is to throw it down the bit-bucket. +#exec 2> /dev/console +## If you wish to trace this script: +#exec 2> "/tmp/${me}_$XBUS_NAME" 1>&2 + +# Our directory in the beginning, so we can use local lab setup +PATH="$dir:/usr/sbin:/sbin:/usr/bin:/bin" + +set -e + +export XBUS_SORT='SORT_LABEL' + +case "$ACTION" in +online) + echo "$ACTION($XBUS_NAME): " | $LOGGER + twinstar enable-wd + sleep 1 # Just for visual effect + asterisk -rx 'module load chan_dahdi.so' 2>&1 | $LOGGER + xpp_blink bzzt xpd "$XBUS_NUM" + ports=`twinstar ports` + if [ "$ports" = 0 ]; then + play /usr/share/dahdi/primary-pbx-is-ready.wav || : + elif [ "$ports" = 1 ]; then + play /usr/share/dahdi/backup-pbx-is-ready.wav || : + fi + echo "online: READY" | $LOGGER + ;; +offline) + echo "$ACTION($XBUS_NAME): " | $LOGGER + twinstar disable-wd + # If we want to disconnect everybody + twinstar jump + asterisk -rx 'module unload chan_dahdi.so' + ;; +*) + echo "$0: Unknown ACTION='$ACTION'" | $LOGGER + echo "$0: ARGS='$*'" | $LOGGER + echo "$0: ENV:" | $LOGGER + env | $LOGGER + exit 1 +esac + diff --git a/xpp/twinstar_setup b/xpp/twinstar_setup new file mode 100755 index 0000000..0e53bdf --- /dev/null +++ b/xpp/twinstar_setup @@ -0,0 +1,155 @@ +#! /usr/bin/perl -w +# +# Written by Oron Peled +# Copyright (C) 2009, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use File::Basename; +BEGIN { + my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); + $ENV{PATH} = "$dir:$ENV{PATH}"; +} + +use Dahdi::Config::Gen qw(is_true); +use Dahdi::Hardware; +use Dahdi::Xpp::Mpp; +use Dahdi::Xpp::Xbus; + +my $xpporder_file = $ENV{XPPORDER_CONF} || "/etc/dahdi/xpp_order"; + +my @devices = Dahdi::Hardware->device_list; +my @xbuses = Dahdi::Xpp::xbuses; + +my $format = "%-20s %-10s # %s\n"; + +sub bad_xpds($) { + my $xbus = shift || die; + my $bad_xpds = 0; + + foreach my $xpd ($xbus->xpds) { + if(! $xpd->spanno) { + my $fqn = $xpd->fqn; + warn "\t$fqn -- Not registered with DAHDI\n"; + $bad_xpds++; + } + } + return $bad_xpds; +} + +sub twinstar_checks() { + my @twinstar_good; + my $first_port; + if(! -d "/sys/bus/astribanks") { + die "CANNOT generate TwinStar setup -- xpp drivers are not loaded\n"; + } + foreach my $dev (@devices) { + my $hwname = $dev->hardware_name; + my $xbus; + my $loaded; + my $tws_port; + my $tws_power; + my $tws_watchdog; + my $mppinfo; + if(! $dev->is_astribank) { + warn "SKIP $hwname -- Only Astribanks can be used for TwinStar\n"; + next; + } + Dahdi::Xpp::Mpp->mpp_addinfo($dev); + $mppinfo = $dev->mppinfo; + if(! defined $mppinfo) { + warn "SKIP $hwname -- is not TwinStar ready\n"; + next; + } + if(! defined $mppinfo->{MPP_TALK}) { + warn "SKIP $hwname -- USB firmware is not loaded\n"; + next; + } + if(! $mppinfo->{TWINSTAR_CAPABLE}) { + warn "SKIP $hwname -- is not TwinStar capable\n"; + next; + } + $xbus = $dev->xbus; + if(! defined $xbus) { + warn "SKIP $hwname -- No XBUS for this device (FPGA firmware? Initialization?)\n"; + next; + } + my $dev = $xbus->transport; + my $connector = $xbus->connector; + my $label = $xbus->label; + my $xbusstr = sprintf "%s (%s) [%s]", $xbus->name, $connector, $label; + if(bad_xpds($xbus)) { + warn "SKIP $xbusstr -- Not registered with DAHDI\n"; + next; + } + my $port = $mppinfo->{TWINSTAR_PORT}; + if(! defined $port) { + warn "SKIP $xbusstr -- Cannot read USB port info\n"; + next; + } + my $power = $mppinfo->{TWINSTAR_POWER}; + if(! defined $power) { + warn "SKIP $xbusstr -- Cannot read USB power info\n"; + next; + } + if(!$power->[0] || !$power->[1]) { + warn "WARNING: Only one cable: $xbusstr\n"; + } + $first_port = $port unless defined $first_port; + printf "GOOD: %-15s port=%d %s\n", $label, $port, $connector; + push(@twinstar_good, $xbus); + if($first_port != $port) { + die + "$0: ", + "XBUS($connector, $label) ", + "connected to PORT $port ", + "(others to $first_port)\n"; + } + } + return @twinstar_good; +} + +my @twinstar_good = twinstar_checks; +if(!@twinstar_good) { + print STDERR "Abort. No Twinstar capable Astribanks found\n"; + exit 1; +} +print "Generating Configuration\n"; +system("dahdi_genconf -v xpporder"); +die "Failed: $?\n" if $?; + +1; + +__END__ + +=head1 NAME + +twinstar_setup - Prepares a server for Astribank TwinStar operation. + +=head1 DESCRIPTION + +This script prepares a server for Astribank TwinStar operation. +The stages are: + +=over + +=item Preliminary checks + +Check that we have only TwinStar capable Astribanks, that the drivers are already loaded. + +=item Configuration Generation + +Indirectly generate the F file that describes the current configuration. +This is done by running C + +This configuration file is used by twinstar_hook(8) to know when all Astribanks has reconnected +to the backup server. + +=item Deployment to Backup Server + +Not implemented yet. Should be done manualy. + +=back diff --git a/xpp/waitfor_xpds b/xpp/waitfor_xpds new file mode 100755 index 0000000..876a0c8 --- /dev/null +++ b/xpp/waitfor_xpds @@ -0,0 +1,163 @@ +#! /bin/sh + +# waitfor_xpds: wait until all Astribanks were initialized +# $Id$ + +# Written by Oron Peled +# Copyright (C) 2008-2009, Xorcom +# +# All rights reserved. +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + + +set -e + +# For lab testing +mydir=`dirname $0` +PATH="${mydir}:${PATH}" +XPP_WAIT_AB_TIMEOUT=100 + +[ -r /etc/dahdi/init.conf ] && . /etc/dahdi/init.conf + +ab_list() { + find /sys/devices -name idVendor 2>/dev/null | \ + xargs grep -H 'e4e4' 2>/dev/null | \ + sed -e 's/idVendor.*/idProduct/' | xargs grep -H '11[3456]' | \ + sed 's,/[^/]*$,,' || : +} + +ab_serial_nums() { + for i in `ab_list`; do + s=`cat "$i/serial" 2>/dev/null` || : + if [ "$s" = '' ]; then + echo "NO-SERIAL" + else + echo "$s" + fi + done | sort -u || : +} + +detected_serial_nums() { + for i in `ls -1d /sys/bus/astribanks/devices/*/transport 2>/dev/null`; do + s=`cat "$i/serial" 2>/dev/null` || : + if [ "$s" = '' ]; then + echo "NO-SERIAL" + else + echo "$s" + fi + done | sort -u || : +} + +calc_union() { + echo "$@" | tr -s ' ' '\n' | sort -u +} + +detected_ab_list() { + # Only check /sys info (don't use /proc anymore). + find /sys/bus/astribanks/devices/*/ -name waitfor_xpds 2> /dev/null || : +} + +waitfor_ab_initialization() { + oldab='' + while + if ! ab=`detected_ab_list`; then + exit 1 + fi + test "$oldab" != "$ab" + do + if [ "$ab" = '' ]; then + echo >&2 "Astribanks disappeared" + break + fi + oldab="$ab" + cat $ab + #echo -n 1>&2 "_" + done +} + +# Any hardware? +if ! dahdi_hardware="`which dahdi_hardware 2>/dev/null`"; then + echo >&2 "$0: Missing dahdi_hardware" + exit 0 +fi + +# Just make sure +if [ "`$dahdi_hardware | grep xpp_usb`" != "" ]; then + astribank_is_starting -v -a +fi +if ! astribank_is_starting; then + # No Astribanks ever seen -- nothing to do + exit 0 +fi + +# Sanity check +for i in `ab_list`; do + s=`cat "$i/serial" 2>/dev/null` || : + if [ "$s" = '' ]; then + echo >&2 "WARNING! Astribank without serial number: $i" + fi +done + +serial_nums=`ab_serial_nums` + +# Loop until detected (hopefully) all astribanks and they are initialized +echo -n 1>&2 "Astribanks detection " +tries="$XPP_WAIT_AB_TIMEOUT" +last_detected=0 +while + new_serial_nums=`ab_serial_nums` + detected_serial_nums=`detected_serial_nums` + curr_union=`calc_union $curr_union $serial_nums $new_serial_nums` + num_detected=`detected_ab_list | wc -l` + if [ "$num_detected" != "$last_detected" ]; then + # Visual feedback (number of detected AB so far) + echo -n 1>&2 "[$num_detected]" + last_detected="$num_detected" + waitfor_ab_initialization > /dev/null + fi + # Break only when we have something and it's stable + test "$curr_union" != "$detected_serial_nums" -o "$detected_serial_nums" = '' +do + if [ "$tries" -le 0 ]; then + echo 1>&2 "TIMEOUT" + exit 1 + fi + echo -n 1>&2 "." + sleep 1 + : $((tries-=1)) + serial_nums="$new_serial_nums" +done + +# Finished: Show a nice output +echo "" +cat /sys/bus/astribanks/devices/*/waitfor_xpds 2> /dev/null || : + +# Wait for device to stabilize and XPD's to finish initalizations +echo 1>&2 "Astribanks initializing spans" +if [ "$XPP_HOTPLUG_DAHDI" = yes -a "$CALLED_FROM_ATRIBANK_HOOK" = '' -a \ + "$ASTERISK_SUPPORTS_DAHDI_HOTPLUG" != 'yes' ]; then + if [ -f /etc/dahdi/xpp_order ]; then + # Now we can wait until the hotplug run would remove the semaphore + echo -n 1>&2 "Other DAHDI initializations... " + astribank_is_starting -v -w 1>&2 + else + echo 1>&2 "WARNING: No ASTERISK_SUPPORTS_DAHDI_HOTPLUG" \ + " and no /etc/dahdi/xpp_order" + fi +fi +# All Astribanks initialized -- remove semaphore +astribank_is_starting -v -r 1>&2 diff --git a/xpp/xpp.rules b/xpp/xpp.rules new file mode 100644 index 0000000..93f772d --- /dev/null +++ b/xpp/xpp.rules @@ -0,0 +1,11 @@ +# Load firmware into the Xorcom Astribank device: +SUBSYSTEM=="usb", ACTION=="add", \ +ENV{PRODUCT}=="e4e4/11[3456][013]/*", ENV{DEVTYPE}!="usb_interface", \ + RUN+="/usr/share/dahdi/xpp_fxloader udev $env{PRODUCT}" + +# Hotplug hook for Astribank up/down +# If you need this functionality, copy the astribank_hook.sample +# to $XPP_INIT_DIR/astribank_hook +# +# By default XPP_INIT_DIR="/usr/share/dahdi" +KERNEL=="xbus*", RUN+="%E{XPP_INIT_DIR}/astribank_hook udev $kernel $sysfs{status} $sysfs{connector}" diff --git a/xpp/xpp_blink b/xpp/xpp_blink new file mode 100755 index 0000000..ff63ae7 --- /dev/null +++ b/xpp/xpp_blink @@ -0,0 +1,168 @@ +#! /usr/bin/perl -w +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use File::Basename; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); } + +use Dahdi; +use Dahdi::Span; +use Dahdi::Xpp; +use Dahdi::Xpp::Xbus; + +sub usage { + die "Usage: $0 {on|off|bzzt} {span | chan | xpd [] | label . That file +shows the current xpp sync master. + +Writing to it, force XPP drivers to use a different sync master + +=back + +=head1 SEE ALSO + +dahdi_registration(1), dahdi_cfg(1), README.Astribank diff --git a/xpp/xpp_timing b/xpp/xpp_timing new file mode 100755 index 0000000..f87215c --- /dev/null +++ b/xpp/xpp_timing @@ -0,0 +1,6 @@ +#! /bin/sh +grep 'DRIFT:' /sys/bus/astribanks/devices/xbus-*/timing | sed \ + -e 's,/sys/bus/astribanks/devices/,,' \ + -e 's,/timing:,: ,' \ + -e 's,DRIFT: ,,' \ + -e 's/^[^:]*:/\U&/' diff --git a/xpp/xtalk/debug.c b/xpp/xtalk/debug.c new file mode 100644 index 0000000..d2d4e15 --- /dev/null +++ b/xpp/xtalk/debug.c @@ -0,0 +1,73 @@ +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +#include +#include +#include +#include +#include +#include +#include + +int verbose = LOG_INFO; +int debug_mask; + +void log_function(int level, int mask, const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + if (verbose >= level) { + if (level < LOG_DEBUG || (mask & debug_mask)) + vfprintf(stderr, msg, ap); + } + va_end(ap); +} + +void dump_packet(int loglevel, int mask, const char *msg, + const char *buf, int len) +{ + int i; + + if (!mask || (mask & debug_mask)) { + log_function(loglevel, ~0, "%-15s:", msg); + for (i = 0; i < len; i++) + log_function(loglevel, ~0, " %02X", (uint8_t)buf[i]); + log_function(loglevel, ~0, "\n"); + } +} + +/* from glibc info(1) */ +void print_backtrace(FILE *fp) +{ + void *array[10]; + size_t size; + char **strings; + size_t i; + + size = backtrace(array, 10); + strings = backtrace_symbols(array, size); + for (i = 0; i < size; i++) + fprintf(fp, "%s\n", strings[i]); + free(strings); +} diff --git a/xpp/xtalk/debug.h b/xpp/xtalk/debug.h new file mode 100644 index 0000000..076cf4a --- /dev/null +++ b/xpp/xtalk/debug.h @@ -0,0 +1,52 @@ +#ifndef DEBUG_H +#define DEBUG_H +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include + +/* + * Each module should define a unique DBG_MASK + */ + +extern int verbose; +extern int debug_mask; + +/* + * Logging + */ +void log_function(int level, int mask, const char *msg, ...) + __attribute__((format(printf, 3, 4))); + +#define ERR(fmt, arg...) log_function(LOG_ERR, 0, "%s:%d: ERROR(%s): " fmt, \ + __FILE__, __LINE__, __func__, ## arg) +#define WARN(fmt, arg...) log_function(LOG_WARNING, 0, "WARNING: " fmt, ## arg) +#define INFO(fmt, arg...) log_function(LOG_INFO, 0, "INFO: " fmt, ## arg) +#define DBG(fmt, arg...) log_function(LOG_DEBUG, DBG_MASK, \ + "%s:%d: DBG(%s): " fmt, __FILE__, __LINE__, __func__, ## arg) + +void dump_packet(int loglevel, int mask, const char *msg, + const char *buf, int len); +void print_backtrace(FILE *fp); + +#endif /* DEBUG_H */ diff --git a/xpp/xtalk/xlist.c b/xpp/xtalk/xlist.c new file mode 100644 index 0000000..d8cd3df --- /dev/null +++ b/xpp/xtalk/xlist.c @@ -0,0 +1,94 @@ +#include +#include +#include +#include + +struct xlist_node *xlist_new(void *data) +{ + struct xlist_node *list; + + list = malloc(sizeof(*list)); + if (!list) + return NULL; + list->next = list; + list->prev = list; + list->data = data; + return list; +} + +void xlist_destroy(struct xlist_node *list, xlist_destructor_t destructor) +{ + struct xlist_node *curr; + struct xlist_node *next; + + if (!list) + return; + curr = list->next; + while (curr != list) { + next = curr->next; + if (destructor) + destructor(curr->data); + memset(curr, 0, sizeof(*curr)); + free(curr); + curr = next; + } + memset(list, 0, sizeof(*list)); + free(list); +} + +void xlist_append_item(struct xlist_node *list, struct xlist_node *item) +{ + assert(list); + assert(xlist_empty(item)); + item->next = list; + item->prev = list->prev; + list->prev->next = item; + list->prev = item; +} + +void xlist_prepend_item(struct xlist_node *list, struct xlist_node *item) +{ + assert(list); + assert(xlist_empty(item)); + item->prev = list; + item->next = list->next; + list->next->prev = item; + list->next = item; +} + +void xlist_remove_item(struct xlist_node *item) +{ + assert(item); + item->prev->next = item->next; + item->next->prev = item->prev; + item->next = item->prev = item; +} + +struct xlist_node *xlist_shift(struct xlist_node *list) +{ + struct xlist_node *item; + + if (!list) + return NULL; + if (xlist_empty(list)) + return NULL; + item = list->next; + xlist_remove_item(item); + return item; +} + +int xlist_empty(const struct xlist_node *list) +{ + assert(list); + return list->next == list && list->prev == list; +} + +size_t xlist_length(const struct xlist_node *list) +{ + struct xlist_node *curr; + size_t count = 0; + + for (curr = list->next; curr != list; curr = curr->next) + count++; + return count; +} diff --git a/xpp/xtalk/xlist.h b/xpp/xtalk/xlist.h new file mode 100644 index 0000000..4f7f818 --- /dev/null +++ b/xpp/xtalk/xlist.h @@ -0,0 +1,29 @@ +#ifndef XLIST_H +#define XLIST_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +struct xlist_node { + void *data; + struct xlist_node *next; + struct xlist_node *prev; +}; + +typedef void (*xlist_destructor_t)(void *data); + +struct xlist_node *xlist_new(void *data); +void xlist_destroy(struct xlist_node *list, xlist_destructor_t destructor); +void xlist_append_item(struct xlist_node *list, struct xlist_node *item); +void xlist_remove_item(struct xlist_node *item); +struct xlist_node *xlist_shift(struct xlist_node *list); +int xlist_empty(const struct xlist_node *list); +size_t xlist_length(const struct xlist_node *list); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XLIST_H */ diff --git a/xpp/xtalk/xtalk.c b/xpp/xtalk/xtalk.c new file mode 100644 index 0000000..ee2b520 --- /dev/null +++ b/xpp/xtalk/xtalk.c @@ -0,0 +1,497 @@ +/* + * Written by Oron Peled + * Copyright (C) 2009, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DBG_MASK 0x02 + +#define TIMEOUT 6000 + +/* + * Base XTALK device. A pointer to this struct + * should be included in the struct representing + * the dialect. + */ +struct xtalk_device { + void *transport_priv; /* e.g: struct xusb */ + struct xtalk_ops ops; + struct xtalk_protocol xproto; + uint8_t xtalk_proto_version; + uint8_t status; + size_t packet_size; + uint16_t tx_sequenceno; +}; + +CMD_DEF(XTALK, ACK, + uint8_t stat; + ); + +CMD_DEF(XTALK, PROTO_GET, + uint8_t proto_version; + uint8_t reserved; + ); + +CMD_DEF(XTALK, PROTO_GET_REPLY, + uint8_t proto_version; + uint8_t reserved; + ); + +union XTALK_PDATA(XTALK) { + MEMBER(XTALK, ACK); + MEMBER(XTALK, PROTO_GET); + MEMBER(XTALK, PROTO_GET_REPLY); +} PACKED members; + +struct xtalk_protocol xtalk_base = { + .name = "XTALK", + .proto_version = 0, + .commands = { + CMD_RECV(XTALK, ACK, NULL), + CMD_SEND(XTALK, PROTO_GET), + CMD_RECV(XTALK, PROTO_GET_REPLY, NULL), + }, + .ack_statuses = { + ACK_STAT(OK, "Acknowledges previous command"), + ACK_STAT(FAIL, "Last command failed"), + ACK_STAT(RESET_FAIL, "reset failed"), + ACK_STAT(NODEST, "No destination is selected"), + ACK_STAT(MISMATCH, "Data mismatch"), + ACK_STAT(NOACCESS, "No access"), + ACK_STAT(BAD_CMD, "Bad command"), + ACK_STAT(TOO_SHORT, "Packet is too short"), + ACK_STAT(ERROFFS, "Offset error (not used)"), + ACK_STAT(NO_LEEPROM, "Large EEPROM was not found"), + ACK_STAT(NO_EEPROM, "No EEPROM was found"), + ACK_STAT(WRITE_FAIL, "Writing to device failed"), + ACK_STAT(NOPWR_ERR, "No power on USB connector"), + } +}; + +void free_command(struct xtalk_command *cmd) +{ + if (!cmd) + return; + memset(cmd, 0, cmd->header.len); + free(cmd); +} + +static const struct xtalk_command_desc *get_command_desc( + const struct xtalk_protocol *xproto, uint8_t op) +{ + const struct xtalk_command_desc *desc; + + if (!xproto) + return NULL; + desc = &xproto->commands[op]; + if (!desc->name) + return NULL; +#if 0 + DBG("%s version=%d, op=0x%X (%s)\n", + xproto->name, xproto->proto_version, + op, desc->name); +#endif + return desc; +} + +static const char *ack_status_msg(const struct xtalk_protocol *xproto, + uint8_t status) +{ + const char *ack_status; + + if (!xproto) + return NULL; + ack_status = xproto->ack_statuses[status]; + DBG("%s status=0x%X (%s)\n", xproto->name, status, ack_status); + return ack_status; +} + +int xtalk_set_protocol(struct xtalk_device *xtalk_dev, + const struct xtalk_protocol *xproto) +{ + const char *protoname = (xproto) ? xproto->name : "GLOBAL"; + int i; + + DBG("%s\n", protoname); + memset(&xtalk_dev->xproto, 0, sizeof(xtalk_dev->xproto)); + for (i = 0; i < MAX_OPS; i++) { + const struct xtalk_command_desc *desc; + + desc = get_command_desc(xproto, i); + if (desc) { + if (!IS_PRIVATE_OP(i)) { + ERR("Bad op=0x%X " + "(should be in the range [0x%X-0x%X]\n", + i, PRIVATE_OP_FIRST, PRIVATE_OP_LAST); + return -EINVAL; + } + xtalk_dev->xproto.commands[i] = *desc; + DBG("private: op=0x%X (%s)\n", i, desc->name); + } else { + if (!IS_PRIVATE_OP(i)) { + const char *name; + + xtalk_dev->xproto.commands[i] = + xtalk_base.commands[i]; + name = xtalk_dev->xproto.commands[i].name; + if (name) + DBG("global: op=0x%X (%s)\n", i, name); + } + } + } + for (i = 0; i < MAX_STATUS; i++) { + const char *stat_msg; + + stat_msg = (xproto) ? xproto->ack_statuses[i] : NULL; + if (stat_msg) { + if (!IS_PRIVATE_OP(i)) { + ERR("Bad status=0x%X " + "(should be in the range [0x%X-0x%X]\n", + i, PRIVATE_OP_FIRST, PRIVATE_OP_LAST); + return -EINVAL; + } + xtalk_dev->xproto.ack_statuses[i] = stat_msg; + DBG("private: status=0x%X (%s)\n", i, stat_msg); + } else { + if (!IS_PRIVATE_OP(i)) { + const char *stat_msg; + + xtalk_dev->xproto.ack_statuses[i] = + xtalk_base.ack_statuses[i]; + stat_msg = xtalk_dev->xproto.ack_statuses[i]; + if (stat_msg) + DBG("global: status=0x%X (%s)\n", + i, stat_msg); + } + } + } + xtalk_dev->xproto.name = protoname; + xtalk_dev->xproto.proto_version = (xproto) ? xproto->proto_version : 0; + return 0; +} + +struct xtalk_command *new_command( + const struct xtalk_device *xtalk_dev, + uint8_t op, uint16_t extra_data) +{ + const struct xtalk_protocol *xproto; + struct xtalk_command *cmd; + const struct xtalk_command_desc *desc; + uint16_t len; + + xproto = &xtalk_dev->xproto; + desc = get_command_desc(xproto, op); + if (!desc) { + ERR("Unknown op=0x%X.\n", op); + return NULL; + } + DBG("OP=0x%X [%s] (extra_data %d)\n", op, desc->name, extra_data); + len = desc->len + extra_data; + cmd = malloc(len); + if (!cmd) { + ERR("Out of memory\n"); + return NULL; + } + if (extra_data) { + uint8_t *ptr = (uint8_t *)cmd; + + DBG("clear extra_data (%d bytes)\n", extra_data); + memset(ptr + desc->len, 0, extra_data); + } + cmd->header.op = op; + cmd->header.len = len; + cmd->header.seq = 0; /* Overwritten in send_usb() */ + return cmd; +} + +void xtalk_dump_command(struct xtalk_command *cmd) +{ + uint16_t len; + int i; + + len = cmd->header.len; + if (len < sizeof(struct xtalk_header)) { + ERR("Command too short (%d)\n", len); + return; + } + INFO("DUMP: OP=0x%X len=%d seq=%d\n", + cmd->header.op, cmd->header.len, cmd->header.seq); + for (i = 0; i < len - sizeof(struct xtalk_header); i++) + INFO(" %2d. 0x%X\n", i, cmd->alt.raw_data[i]); +} + +static int send_command(struct xtalk_device *xtalk_dev, + struct xtalk_command *cmd, int timeout) +{ + int ret; + int len; + void *priv = xtalk_dev->transport_priv; + + len = cmd->header.len; + cmd->header.seq = xtalk_dev->tx_sequenceno; + + ret = xtalk_dev->ops.send_func(priv, (char *)cmd, len, timeout); + if (ret < 0) + DBG("send_func failed ret=%d\n", ret); + xtalk_dev->tx_sequenceno++; + return ret; +} + +static struct xtalk_command *recv_command(struct xtalk_device *xtalk_dev, + int timeout) +{ + struct xtalk_command *reply; + void *priv = xtalk_dev->transport_priv; + size_t psize = xtalk_dev->packet_size; + int ret; + + reply = malloc(psize); + if (!reply) { + ERR("Out of memory\n"); + goto err; + } + reply->header.len = 0; + ret = xtalk_dev->ops.recv_func(priv, (char *)reply, psize, timeout); + if (ret < 0) { + ERR("Receive from usb failed.\n"); + goto err; + } else if (ret == 0) { + goto err; /* No reply */ + } + if (ret != reply->header.len) { + ERR("Wrong length received: got %d bytes, " + "but length field says %d bytes%s\n", + ret, reply->header.len, + (ret == 1) ? ". Old USB firmware?" : ""); + goto err; + } + /* dump_packet(LOG_DEBUG, DBG_MASK, __func__, (char *)reply, ret); */ + return reply; +err: + if (reply) { + memset(reply, 0, psize); + free_command(reply); + } + return NULL; +} + + +__attribute__((warn_unused_result)) +int process_command( + struct xtalk_device *xtalk_dev, + struct xtalk_command *cmd, + struct xtalk_command **reply_ref) +{ + const struct xtalk_protocol *xproto; + struct xtalk_command *reply = NULL; + const struct xtalk_command_desc *reply_desc; + const struct xtalk_command_desc *expected; + const struct xtalk_command_desc *cmd_desc; + uint8_t reply_op; + const char *protoname; + int ret; + + xproto = &xtalk_dev->xproto; + protoname = (xproto) ? xproto->name : "GLOBAL"; + /* So the caller knows if a reply was received */ + if (reply_ref) + *reply_ref = NULL; + reply_op = cmd->header.op | XTALK_REPLY_MASK; + cmd_desc = get_command_desc(xproto, cmd->header.op); + expected = get_command_desc(xproto, reply_op); + ret = send_command(xtalk_dev, cmd, TIMEOUT); + if (!reply_ref) { + DBG("No reply requested\n"); + goto out; + } + if (ret < 0) { + ERR("send_command failed: %d\n", ret); + goto out; + } + reply = recv_command(xtalk_dev, TIMEOUT); + if (!reply) { + ERR("recv_command failed\n"); + ret = -EPROTO; + goto out; + } + *reply_ref = reply; + if ((reply->header.op & 0x80) != 0x80) { + ERR("Unexpected reply op=0x%02X, should have MSB set.\n", + reply->header.op); + ret = -EPROTO; + goto out; + } + DBG("REPLY OP: 0x%X\n", reply->header.op); + reply_desc = get_command_desc(xproto, reply->header.op); + if (!reply_desc) { + ERR("Unknown reply (proto=%s) op=0x%02X\n", + protoname, reply->header.op); + ret = -EPROTO; + goto out; + } + DBG("REPLY NAME: %s\n", reply_desc->name); + if (reply->header.op == XTALK_ACK) { + int status = CMD_FIELD(reply, XTALK, ACK, stat); + + if (expected) { + ERR("Expected OP=0x%02X: Got ACK(%d): %s\n", + reply_op, + status, + ack_status_msg(xproto, status)); + ret = -EPROTO; + goto out; + } else if (status != STAT_OK) { + + ERR("Got ACK (for OP=0x%X [%s]): %d %s\n", + cmd->header.op, + cmd_desc->name, + status, ack_status_msg(xproto, status)); + ret = -EPROTO; + goto out; + } + /* Good expected ACK ... */ + } else if (reply->header.op != reply_op) { + ERR("Expected OP=0x%02X: Got OP=0x%02X\n", + reply_op, reply->header.op); + ret = -EPROTO; + goto out; + } + if (expected && expected->len > reply->header.len) { + ERR("Expected len=%d: Got len=%d\n", + expected->len, reply->header.len); + ret = -EPROTO; + goto out; + } + if (cmd->header.seq != reply->header.seq) { + ERR("Expected seq=%d: Got seq=%d\n", + cmd->header.seq, reply->header.seq); + ret = -EPROTO; + goto out; + } + ret = reply->header.len; /* All good, return the length */ + DBG("returning reply op 0x%X (%d bytes)\n", reply->header.op, ret); +out: + free_command(cmd); + if (!reply_ref && reply) + free_command(reply); + return ret; +} + +/* + * Protocol Commands + */ + +int xtalk_proto_query(struct xtalk_device *xtalk_dev) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + uint8_t proto_version; + int ret; + + DBG("\n"); + assert(xtalk_dev != NULL); + proto_version = xtalk_dev->xproto.proto_version; + cmd = new_command(xtalk_dev, XTALK_PROTO_GET, 0); + if (!cmd) { + ERR("new_command failed\n"); + return -ENOMEM; + } + /* Protocol Version */ + CMD_FIELD(cmd, XTALK, PROTO_GET, proto_version) = proto_version; + ret = process_command(xtalk_dev, cmd, &reply); + if (ret < 0) { + ERR("process_command failed: %d\n", ret); + goto out; + } + xtalk_dev->xtalk_proto_version = + CMD_FIELD(reply, XTALK, PROTO_GET_REPLY, proto_version); + if (xtalk_dev->xtalk_proto_version != proto_version) { + DBG("Got %s protocol version: 0x%02x (expected 0x%02x)\n", + xtalk_dev->xproto.name, + xtalk_dev->xtalk_proto_version, + proto_version); + ret = xtalk_dev->xtalk_proto_version; + goto out; + } + DBG("Protocol version: %02x\n", xtalk_dev->xtalk_proto_version); + ret = xtalk_dev->xtalk_proto_version; +out: + free_command(reply); + return ret; +} + +/* + * Wrappers + */ + +struct xtalk_device *xtalk_new(const struct xtalk_ops *ops, + size_t packet_size, void *priv) +{ + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(ops != NULL); + xtalk_dev = malloc(sizeof(*xtalk_dev)); + if (!xtalk_dev) { + ERR("Allocating XTALK device memory failed\n"); + return NULL; + } + memset(xtalk_dev, 0, sizeof(*xtalk_dev)); + memcpy((void *)&xtalk_dev->ops, (const void *)ops, + sizeof(xtalk_dev->ops)); + xtalk_dev->transport_priv = priv; + xtalk_dev->packet_size = packet_size; + xtalk_dev->tx_sequenceno = 1; + ret = xtalk_set_protocol(xtalk_dev, NULL); + if (ret < 0) { + ERR("GLOBAL Protocol registration failed: %d\n", ret); + goto err; + } + return xtalk_dev; + +err: + if (xtalk_dev) + xtalk_delete(xtalk_dev); + return NULL; +} + +void xtalk_delete(struct xtalk_device *xtalk_dev) +{ + void *priv; + + if (!xtalk_dev) + return; + DBG("\n"); + priv = xtalk_dev->transport_priv; + assert(priv); + xtalk_dev->tx_sequenceno = 0; + assert(&xtalk_dev->ops != NULL); + assert(&xtalk_dev->ops.close_func != NULL); + xtalk_dev->ops.close_func(priv); +} diff --git a/xpp/xtalk/xtalk.h b/xpp/xtalk/xtalk.h new file mode 100644 index 0000000..88f0260 --- /dev/null +++ b/xpp/xtalk/xtalk.h @@ -0,0 +1,178 @@ +#ifndef XTALK_H +#define XTALK_H +/* + * Written by Oron Peled + * Copyright (C) 2009, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* + * XTALK - Base protocol for our USB devices + * It is meant to provide a common base for layered + * protocols (dialects) + */ + +#include +#include +/* Definitions common to the firmware (in include/ directory) */ +#include + +#ifdef __GNUC__ +#define PACKED __attribute__((packed)) +#else +#error "We do not know how your compiler packs structures" +#endif + +struct xtalk_device; +struct xtalk_command_desc; + +typedef int (*xtalk_cmd_callback_t)( + struct xtalk_device *xtalk_dev, + struct xtalk_command_desc *xtalk_cmd); + +/* Describe a single xtalk command */ +struct xtalk_command_desc { + uint8_t op; + const char *name; + xtalk_cmd_callback_t callback; + uint16_t len; /* Minimal length */ +}; + +/* Define a complete protocol */ +struct xtalk_protocol { + const char *name; + uint8_t proto_version; + struct xtalk_command_desc commands[MAX_OPS]; + const char *ack_statuses[MAX_STATUS]; +}; + +/* + * The common header of every xtalk command + * in every xtalk dialect. + */ +struct xtalk_header { + uint16_t len; + uint16_t seq; + uint8_t op; /* MSB: 0 - to device, 1 - from device */ +} PACKED; + +struct xtalk_command { + /* Common part */ + struct xtalk_header header; + /* Each dialect has its own data members */ + union private_data { + uint8_t raw_data[0]; + } PACKED alt; +} PACKED; + +/* + * Macros to unify access to protocol packets and fields: + * p - signify the dialect prefix (XTALK for base protocol) + * o - signify command op (e.g: ACK) + * cmd - A pointer to struct xtalk_command + * field - field name (e.g: raw_data) + */ +#define XTALK_STRUCT(p, o) p ## _struct_ ## o +#define XTALK_PDATA(o) xtalk_privdata_ ## o +#define XTALK_CMD_PTR(cmd, p) ((union XTALK_PDATA(p)*)&((cmd)->alt)) +#define CMD_FIELD(cmd, p, o, field) \ + (XTALK_CMD_PTR(cmd, p)->XTALK_STRUCT(p, o).field) +#define CMD_DEF(p, o, ...) struct XTALK_STRUCT(p, o) { \ + __VA_ARGS__ \ + } PACKED XTALK_STRUCT(p, o) +#define MEMBER(p, o) struct XTALK_STRUCT(p, o) XTALK_STRUCT(p, o) + +/* Wrappers for transport (xusb) functions */ +struct xtalk_ops { + int (*send_func)(void *transport_priv, void *data, size_t len, + int timeout); + int (*recv_func)(void *transport_priv, void *data, size_t maxlen, + int timeout); + int (*close_func)(void *transport_priv); +}; + +/* + * Base XTALK device. A pointer to this struct + * should be included in the struct representing + * the dialect. + */ +struct xtalk_device; + +/* high-level */ +struct xtalk_device *xtalk_new(const struct xtalk_ops *ops, + size_t packet_size, void *transport_priv); +void xtalk_delete(struct xtalk_device *dev); +int xtalk_set_protocol(struct xtalk_device *xtalk_dev, + const struct xtalk_protocol *xproto); +int xtalk_proto_query(struct xtalk_device *dev); +void xtalk_dump_command(struct xtalk_command *cmd); + +/* low-level */ +int process_command( + struct xtalk_device *dev, + struct xtalk_command *cmd, + struct xtalk_command **reply_ref); +struct xtalk_command *new_command( + const struct xtalk_device *xtalk_dev, + uint8_t op, uint16_t extra_data); +void free_command(struct xtalk_command *cmd); + +/* + * Convenience macros to define entries in a protocol command table: + * p - signify the dialect prefix (XTALK for base protocol) + * o - signify command op (e.g: ACK) + * cb - A callback function (type xtalk_cmd_callback_t) + */ +#define CMD_RECV(p, o, cb) \ + [p ## _ ## o | XTALK_REPLY_MASK] = { \ + .op = (p ## _ ## o) | XTALK_REPLY_MASK, \ + .name = (#o "_reply"), \ + .callback = (cb), \ + .len = \ + sizeof(struct xtalk_header) + \ + sizeof(struct XTALK_STRUCT(p, o)), \ + } + +#define CMD_SEND(p, o) \ + [p ## _ ## o] = { \ + .op = (p ## _ ## o), \ + .name = (#o), \ + .callback = NULL, \ + .len = \ + sizeof(struct xtalk_header) + \ + sizeof(struct XTALK_STRUCT(p, o)), \ + } + +/* + * Convenience macro to define statuses: + * x - status code (e.g: OK) + * m - status message (const char *) + */ +#define ACK_STAT(x, m) [STAT_ ## x] = (m) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XTALK_H */ diff --git a/xpp/xtalk/xtalk_defs.h b/xpp/xtalk/xtalk_defs.h new file mode 100644 index 0000000..826ad67 --- /dev/null +++ b/xpp/xtalk/xtalk_defs.h @@ -0,0 +1,41 @@ +#ifndef XTALK_DEFS_H +#define XTALK_DEFS_H + +#define MAX_OPS 256 /* single byte */ +#define MAX_STATUS 256 /* single byte */ + +#define XTALK_REPLY_MASK 0x80 /* Every reply has this bit */ + +#define PRIVATE_OP_FIRST 0x05 +#define PRIVATE_OP_LAST 0x7F +#define IS_PRIVATE_OP(x) ( \ + (((x) & ~(XTALK_REPLY_MASK)) >= PRIVATE_OP_FIRST) && \ + (((x) & ~(XTALK_REPLY_MASK)) <= PRIVATE_OP_LAST) \ + ) + +#define XTALK_ACK 0x80 +#define XTALK_PROTO_GET 0x01 +#define XTALK_PROTO_GET_REPLY (XTALK_PROTO_GET | XTALK_REPLY_MASK) +#define XTALK_FWVERS_GET 0x11 +#define XTALK_FWVERS_GET_REPLY (XTALK_FWVERS_GET | XTALK_REPLY_MASK) +/* Get EEPROM table contents Product/Vendor Id ... */ +#define XTALK_CAPS_GET 0x0E +#define XTALK_CAPS_GET_REPLY (XTALK_CAPS_GET | XTALK_REPLY_MASK) + +/*------------- XTALK: statuses in ACK ---------------------------------------*/ +#define STAT_OK 0x00 /* OK */ +#define STAT_FAIL 0x01 /* last command failed */ +#define STAT_RESET_FAIL 0x02 /* reset failed */ +#define STAT_NODEST 0x03 /* No destination is selected */ +#define STAT_MISMATCH 0x04 /* Data mismatch */ +#define STAT_NOACCESS 0x05 /* No access */ +#define STAT_BAD_CMD 0x06 /* Bad command */ +#define STAT_TOO_SHORT 0x07 /* Packet is too short */ +#define STAT_ERROFFS 0x08 /* Offset error (not used) */ +#define STAT_NO_LEEPROM 0x0A /* Large EEPROM was not found */ +#define STAT_NO_EEPROM 0x0B /* No EEPROM was found */ +#define STAT_WRITE_FAIL 0x0C /* Writing to device failed */ +#define STAT_NOPWR_ERR 0x10 /* No power on USB connector */ + + +#endif /* XTALK_DEFS_H */ diff --git a/xpp/xtalk/xusb.c b/xpp/xtalk/xusb.c new file mode 100644 index 0000000..d33f013 --- /dev/null +++ b/xpp/xtalk/xusb.c @@ -0,0 +1,943 @@ +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#define _GNU_SOURCE /* for memrchr() */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DBG_MASK 0x01 +#define TIMEOUT 500 +#define MAX_RETRIES 10 + +struct xusb { + struct usb_device *dev; + usb_dev_handle *handle; + const struct xusb_spec *spec; + char iManufacturer[BUFSIZ]; + char iProduct[BUFSIZ]; + char iSerialNumber[BUFSIZ]; + char iInterface[BUFSIZ]; + char devpath_tail[PATH_MAX + 1]; + int bus_num; + int device_num; + int interface_num; + int ep_out; + int ep_in; + int is_usb2; + int is_claimed; + int is_open; + size_t packet_size; +}; + +static void xusb_init(); + +/* + * XTALK_OPTIONS: + * A white-space separated list of options, read from the environment + * variable of that name. Existing options: + * + * - "use-clear-halt" -- force USB "clear_halt" operation during + * device initialization (this is the default) + * - "no-use-clear-halt" -- force no USB "clear_halt" operation during + * device initialization + * - "no-lock" -- prevent using global sempahore to serialize libusb + * initialization. Previously done via "XUSB_NOLOCK" + * environment variable. + */ +int xtalk_parse_options(void); +int xtalk_option_use_clear_halt(void); +int xtalk_option_no_lock(void); + +void xusb_init_spec(struct xusb_spec *spec, char *name, + uint16_t vendor_id, uint16_t product_id, + int nifaces, int iface, int nep, int ep_out, int ep_in) +{ + DBG("Initialize %s: interfaces=%d using interface num=%d endpoints=%d " + "(OUT=0x%02X, IN=0x%02X)\n", + name, nifaces, iface, nep, ep_out, ep_in); + memset(spec, 0, sizeof(*spec)); + spec->name = name; + spec->num_interfaces = nifaces; + spec->my_interface_num = iface; + spec->num_endpoints = nep; + spec->my_vendor_id = vendor_id; + spec->my_product_id = product_id; + spec->my_ep_in = ep_in; + spec->my_ep_out = ep_out; +} + +#define EP_OUT(xusb) ((xusb)->spec->my_ep_out) +#define EP_IN(xusb) ((xusb)->spec->my_ep_in) + +/* + * USB handling + */ + +static int get_usb_string(struct xusb *xusb, uint8_t item, char *buf) +{ + char tmp[BUFSIZ]; + int ret; + + assert(xusb->handle); + if (!item) + return 0; + ret = usb_get_string_simple(xusb->handle, item, tmp, BUFSIZ); + if (ret <= 0) + return ret; + return snprintf(buf, BUFSIZ, "%s", tmp); +} + +static const struct usb_interface_descriptor *get_interface( + const struct usb_device *dev, + int my_interface_num, + int num_interfaces) +{ + const struct usb_interface *interface; + const struct usb_interface_descriptor *iface_desc; + const struct usb_config_descriptor *config_desc; + int num_altsetting; + + config_desc = dev->config; + if (!config_desc) { + ERR("No configuration descriptor: strange USB1 controller?\n"); + return NULL; + } + if (num_interfaces && config_desc->bNumInterfaces != num_interfaces) { + DBG("Wrong number of interfaces: have %d need %d\n", + config_desc->bNumInterfaces, num_interfaces); + return NULL; + } + interface = &config_desc->interface[my_interface_num]; + assert(interface != NULL); + iface_desc = interface->altsetting; + num_altsetting = interface->num_altsetting; + assert(num_altsetting != 0); + assert(iface_desc != NULL); + return iface_desc; +} + +static int match_interface(const struct usb_device *dev, + const struct xusb_spec *spec) +{ + const struct usb_device_descriptor *dev_desc; + const struct usb_interface_descriptor *iface_desc; + + dev_desc = &dev->descriptor; + assert(dev_desc); + DBG("Checking: %04X:%04X interfaces=%d interface num=%d endpoints=%d: " + "\"%s\"\n", + spec->my_vendor_id, + spec->my_product_id, + spec->num_interfaces, + spec->my_interface_num, + spec->num_endpoints, + spec->name); + if (dev_desc->idVendor != spec->my_vendor_id) { + DBG("Wrong vendor id 0x%X\n", dev_desc->idVendor); + return 0; + } + if (dev_desc->idProduct != spec->my_product_id) { + DBG("Wrong product id 0x%X\n", dev_desc->idProduct); + return 0; + } + iface_desc = get_interface(dev, spec->my_interface_num, + spec->num_interfaces); + if (!iface_desc) { + ERR("Could not get interface descriptor of device: %s\n", + usb_strerror()); + return 0; + } + if (iface_desc->bInterfaceClass != 0xFF) { + DBG("Wrong interface class 0x%X\n", + iface_desc->bInterfaceClass); + return 0; + } + if (iface_desc->bInterfaceNumber != spec->my_interface_num) { + DBG("Wrong interface number %d (expected %d)\n", + iface_desc->bInterfaceNumber, spec->my_interface_num); + return 0; + } + if (iface_desc->bNumEndpoints != spec->num_endpoints) { + DBG("Wrong number of endpoints %d\n", + iface_desc->bNumEndpoints); + return 0; + } + return 1; +} + +#define GET_USB_STRING(xusb, from, item) \ + get_usb_string((xusb), (from)->item, xusb->item) + +static int xusb_fill_strings(struct xusb *xusb) +{ + const struct usb_device_descriptor *dev_desc; + const struct usb_interface_descriptor *iface_desc; + + + dev_desc = &xusb->dev->descriptor; + assert(dev_desc); + if (GET_USB_STRING(xusb, dev_desc, iManufacturer) < 0) { + ERR("Failed reading iManufacturer string: %s\n", + usb_strerror()); + return 0; + } + if (GET_USB_STRING(xusb, dev_desc, iProduct) < 0) { + ERR("Failed reading iProduct string: %s\n", + usb_strerror()); + return 0; + } + if (GET_USB_STRING(xusb, dev_desc, iSerialNumber) < 0) { + ERR("Failed reading iSerialNumber string: %s\n", + usb_strerror()); + return 0; + } + iface_desc = get_interface(xusb->dev, xusb->interface_num, 0); + if (!iface_desc) { + ERR("Could not get interface descriptor of device: %s\n", + usb_strerror()); + return 0; + } + if (GET_USB_STRING(xusb, iface_desc, iInterface) < 0) { + ERR("Failed reading iInterface string: %s\n", usb_strerror()); + return 0; + } + return 1; +} + +static int xusb_open(struct xusb *xusb) +{ + assert(xusb); + if (xusb->is_open) + return 1; + xusb->handle = usb_open(xusb->dev); + if (!xusb->handle) { + ERR("Failed to open usb device '%s': %s\n", + xusb->devpath_tail, usb_strerror()); + return 0; + } + xusb->is_open = 1; + return 1; +} + +int xusb_claim_interface(struct xusb *xusb) +{ + const struct usb_device_descriptor *dev_desc; + int ret; + + assert(xusb); + xusb_open(xusb); /* If it's not open yet... */ + if (usb_claim_interface(xusb->handle, xusb->interface_num) != 0) { + ERR("usb_claim_interface %d in '%s': %s\n", + xusb->interface_num, + xusb->devpath_tail, + usb_strerror()); + return 0; + } + xusb->is_claimed = 1; + xusb_fill_strings(xusb); + dev_desc = &xusb->dev->descriptor; + DBG("ID=%04X:%04X Manufacturer=[%s] Product=[%s] " + "SerialNumber=[%s] Interface=[%s]\n", + dev_desc->idVendor, + dev_desc->idProduct, + xusb->iManufacturer, + xusb->iProduct, + xusb->iSerialNumber, + xusb->iInterface); + if (xtalk_option_use_clear_halt()) { + DBG("Using clear_halt()\n"); + if (usb_clear_halt(xusb->handle, EP_OUT(xusb)) != 0) { + ERR("Clearing output endpoint: %s\n", usb_strerror()); + return 0; + } + if (usb_clear_halt(xusb->handle, EP_IN(xusb)) != 0) { + ERR("Clearing input endpoint: %s\n", usb_strerror()); + return 0; + } + } + ret = xusb_flushread(xusb); + if (ret < 0) { + ERR("xusb_flushread failed: %d\n", ret); + return 0; + } + return 1; +} + +static void xusb_list_dump(struct xlist_node *xusb_list) +{ + struct xlist_node *curr; + struct xusb *xusb; + + for (curr = xusb_list->next; curr != xusb_list; curr = curr->next) { + struct usb_device *dev; + struct usb_bus *bus; + struct usb_device_descriptor *dev_desc; + + xusb = curr->data; + assert(xusb); + dev = xusb->dev; + assert(dev); + bus = dev->bus; + assert(bus); + dev_desc = &dev->descriptor; + assert(dev_desc); + DBG("usb:ID=%04X:%04X [%s / %s / %s], (%s/%s)\n", + dev_desc->idVendor, + dev_desc->idProduct, + xusb->iManufacturer, + xusb->iProduct, + xusb->iSerialNumber, + bus->dirname, + dev->filename + ); + } +} + +void xusb_destroy(struct xusb *xusb) +{ + if (xusb) { + xusb_close(xusb); + memset(xusb, 0, sizeof(*xusb)); + free(xusb); + } +} + +static struct xusb *xusb_new(struct usb_device *dev, + const struct xusb_spec *spec) +{ + struct usb_device_descriptor *dev_desc; + struct usb_config_descriptor *config_desc; + struct usb_interface *interface; + struct usb_interface_descriptor *iface_desc; + struct usb_endpoint_descriptor *endpoint; + size_t max_packet_size; + int i; + struct xusb *xusb = NULL; + + /* + * Get information from the usb_device + */ + dev_desc = &dev->descriptor; + if (!dev_desc) { + ERR("usb device without a device descriptor\n"); + goto fail; + } + config_desc = dev->config; + if (!config_desc) { + ERR("usb device without a configuration descriptor\n"); + goto fail; + } + interface = &config_desc->interface[spec->my_interface_num]; + iface_desc = interface->altsetting; + endpoint = iface_desc->endpoint; + /* Calculate max packet size */ + max_packet_size = PACKET_SIZE; + for (i = 0; i < iface_desc->bNumEndpoints; i++, endpoint++) { + DBG("Validating endpoint @ %d (interface %d)\n", + i, spec->my_interface_num); + if (endpoint->bEndpointAddress == spec->my_ep_out || + endpoint->bEndpointAddress == spec->my_ep_in) { + if (endpoint->wMaxPacketSize > PACKET_SIZE) { + ERR("EP #%d wMaxPacketSize too large (%d)\n", + i, endpoint->wMaxPacketSize); + goto fail; + } + if (endpoint->wMaxPacketSize < max_packet_size) + max_packet_size = endpoint->wMaxPacketSize; + } + } + /* Fill xusb */ + xusb = malloc(sizeof(*xusb)); + if (!xusb) { + ERR("Out of memory"); + goto fail; + } + memset(xusb, 0, sizeof(*xusb)); + xusb->dev = dev; + xusb->spec = spec; + sscanf(dev->bus->dirname, "%d", &xusb->bus_num); + sscanf(dev->filename, "%d", &xusb->device_num); + snprintf(xusb->devpath_tail, PATH_MAX, "%03d/%03d", + xusb->bus_num, xusb->device_num); + xusb->interface_num = spec->my_interface_num; + xusb->ep_out = spec->my_ep_out; + xusb->ep_in = spec->my_ep_in; + xusb->packet_size = max_packet_size; + xusb->is_usb2 = (max_packet_size == 512); + if (!xusb_open(xusb)) { + ERR("Failed opening device: %04X:%04X - %s\n", + dev_desc->idVendor, + dev_desc->idProduct, + xusb->devpath_tail); + goto fail; + } + DBG("%04X:%04X - %s\n", + dev_desc->idVendor, + dev_desc->idProduct, + xusb->devpath_tail); + return xusb; +fail: + xusb_destroy(xusb); + return NULL; +} + +struct xusb *xusb_find_iface(const char *devpath, + int iface_num, + int ep_out, + int ep_in, + struct xusb_spec *dummy_spec) +{ + struct usb_bus *bus; + + DBG("\n"); + xusb_init(); + for (bus = usb_get_busses(); bus; bus = bus->next) { + int bus_num; + char tmppath[PATH_MAX + 1]; + struct usb_device *dev; + + tmppath[0] = '\0'; + sscanf(bus->dirname, "%d", &bus_num); + snprintf(tmppath, sizeof(tmppath), "%03d", bus_num); + DBG("Check bus %d: %s ? %s\n", bus_num, tmppath, devpath); + if (strncmp(tmppath, devpath, strlen(tmppath)) != 0) + continue; + DBG("Matched bus %d\n", bus_num); + for (dev = bus->devices; dev; dev = dev->next) { + struct usb_device_descriptor *dev_desc; + struct usb_config_descriptor *config_desc; + struct usb_interface *interface; + struct xusb *xusb; + int device_num; + + sscanf(dev->filename, "%d", &device_num); + DBG("Check device %d\n", device_num); + snprintf(tmppath, sizeof(tmppath), "%03d/%03d", + bus_num, device_num); + if (strncmp(tmppath, devpath, strlen(tmppath)) != 0) + continue; + dev_desc = &dev->descriptor; + assert(dev_desc); + config_desc = dev->config; + assert(config_desc); + interface = config_desc->interface; + assert(interface); + DBG("Matched device %s: %X:%X\n", tmppath, + dev_desc->idVendor, dev_desc->idProduct); + assert(dummy_spec); + xusb_init_spec(dummy_spec, "", + dev_desc->idVendor, dev_desc->idProduct, + config_desc->bNumInterfaces, + iface_num, + interface->altsetting->bNumEndpoints, + ep_out, ep_in); + xusb = xusb_new(dev, dummy_spec); + if (!xusb) + ERR("xusb allocation failed\n"); + return xusb; + } + } + return NULL; +} + +static const char *path_tail(const char *path) +{ + const char *p; + + assert(path != NULL); + /* Find last '/' */ + p = memrchr(path, '/', strlen(path)); + if (!p) { + ERR("Missing a '/' in %s\n", path); + return NULL; + } + /* Search for a '/' before that */ + p = memrchr(path, '/', p - path); + if (!p) + p = path; /* No more '/' */ + else + p++; /* skip '/' */ + return p; +} + +int xusb_filter_bypath(const struct xusb *xusb, void *data) +{ + const char *p; + const char *path = data; + + DBG("%s\n", path); + assert(path != NULL); + p = path_tail(path); + if (strcmp(xusb->devpath_tail, p) != 0) { + DBG("device path missmatch: '%s' != '%s'\n", + xusb->devpath_tail, p); + return 0; + } + return 1; +} + +struct xusb *xusb_find_bypath(const struct xusb_spec *specs, int numspecs, + const char *path) +{ + struct xlist_node *xlist; + struct xlist_node *head; + struct xusb *xusb; + + xlist = xusb_find_byproduct(specs, numspecs, + xusb_filter_bypath, (void *)path); + head = xlist_shift(xlist); + if (!head) + return NULL; + if (!xlist_empty(xlist)) { + ERR("Too many matches (extra %zd) to '%s'\n", + xlist_length(xlist), path); + return NULL; + } + xusb = head->data; + xlist_destroy(xlist, NULL); + return xusb; +} + +struct xlist_node *xusb_find_byproduct(const struct xusb_spec *specs, + int numspecs, xusb_filter_t filterfunc, void *data) +{ + struct xlist_node *xlist; + struct usb_bus *bus; + struct usb_device *dev; + + DBG("specs(%d)\n", numspecs); + xlist = xlist_new(NULL); + if (!xlist) { + ERR("Failed allocation new xlist"); + goto fail_xlist; + } + xusb_init(); + for (bus = usb_get_busses(); bus; bus = bus->next) { + for (dev = bus->devices; dev; dev = dev->next) { + struct usb_device_descriptor *dev_desc; + struct xlist_node *item; + int i; + + dev_desc = &dev->descriptor; + assert(dev_desc); + DBG("usb:%s/%s: ID=%04X:%04X\n", + dev->bus->dirname, + dev->filename, + dev_desc->idVendor, + dev_desc->idProduct); + for (i = 0; i < numspecs; i++) { + struct xusb *xusb; + const struct xusb_spec *sp = &specs[i]; + + if (!match_interface(dev, sp)) + continue; + xusb = xusb_new(dev, sp); + if (!xusb) { + ERR("xusb allocation failed\n"); + goto fail_malloc; + } + if (filterfunc && !filterfunc(xusb, data)) { + xusb_destroy(xusb); + continue; + } + item = xlist_new(xusb); + xlist_append_item(xlist, item); + break; + } + } + } + xusb_list_dump(xlist); + return xlist; +fail_malloc: + xlist_destroy(xlist, NULL); +fail_xlist: + return NULL; +} + +struct xusb *xusb_open_one(const struct xusb_spec *specs, int numspecs, + xusb_filter_t filterfunc, void *data) +{ + struct xlist_node *xusb_list; + struct xlist_node *curr; + int num; + struct xusb *xusb = NULL; + + xusb_list = xusb_find_byproduct(specs, numspecs, filterfunc, data); + num = xlist_length(xusb_list); + DBG("total %d devices\n", num); + switch (num) { + case 0: + ERR("No matching device.\n"); + break; + case 1: + curr = xlist_shift(xusb_list); + xusb = curr->data; + xlist_destroy(curr, NULL); + xlist_destroy(xusb_list, NULL); + if (!xusb_claim_interface(xusb)) { + xusb_destroy(xusb); + return NULL; + } + xusb_showinfo(xusb); + break; + default: + ERR("Too many devices (%d). Aborting.\n", num); + break; + } + return xusb; +} + +int xusb_interface(struct xusb *xusb) +{ + return xusb->interface_num; +} + +size_t xusb_packet_size(const struct xusb *xusb) +{ + return xusb->packet_size; +} + +/* + * MP device handling + */ +void xusb_showinfo(const struct xusb *xusb) +{ + struct usb_device_descriptor *dev_desc; + struct usb_device *dev; + + assert(xusb != NULL); + dev = xusb->dev; + dev_desc = &dev->descriptor; + if (verbose <= LOG_INFO) { + INFO("usb:%s/%s: ID=%04X:%04X [%s / %s / %s]\n", + dev->bus->dirname, + dev->filename, + dev_desc->idVendor, + dev_desc->idProduct, + xusb->iManufacturer, + xusb->iProduct, + xusb->iSerialNumber); + } else { + printf("USB Bus/Device: [%s/%s] (%s,%s)\n", + dev->bus->dirname, + dev->filename, + (xusb->is_open) ? "open" : "closed", + (xusb->is_claimed) ? "claimed" : "unused"); + printf("USB Spec name: [%s]\n", xusb->spec->name); + printf("USB iManufacturer: [%s]\n", xusb->iManufacturer); + printf("USB iProduct: [%s]\n", xusb->iProduct); + printf("USB iSerialNumber: [%s]\n", xusb->iSerialNumber); + } +} + +const char *xusb_serial(const struct xusb *xusb) +{ + return xusb->iSerialNumber; +} + +const char *xusb_devpath(const struct xusb *xusb) +{ + return xusb->devpath_tail; +} + +const char *xusb_manufacturer(const struct xusb *xusb) +{ + return xusb->iManufacturer; +} + +const char *xusb_product(const struct xusb *xusb) +{ + return xusb->iProduct; +} + +uint16_t xusb_vendor_id(const struct xusb *xusb) +{ + return xusb->dev->descriptor.idVendor; +} + +uint16_t xusb_product_id(const struct xusb *xusb) +{ + return xusb->dev->descriptor.idProduct; +} + +const struct xusb_spec *xusb_spec(const struct xusb *xusb) +{ + return xusb->spec; +} + +int xusb_close(struct xusb *xusb) +{ + if (xusb) { + if (xusb->handle) { + assert(xusb->spec); + assert(xusb->spec->name); + DBG("Closing interface \"%s\"\n", xusb->spec->name); + if (xusb->is_claimed) { + if (usb_release_interface(xusb->handle, + xusb->spec->my_interface_num) != 0) + ERR("Releasing interface: usb: %s\n", + usb_strerror()); + xusb->is_claimed = 0; + } + if (xusb->is_open) { + if (usb_close(xusb->handle) != 0) { + ERR("Closing device: usb: %s\n", + usb_strerror()); + } + xusb->is_open = 0; + } + xusb->handle = NULL; + } + xusb = NULL; + } + return 0; +} + +int xusb_send(struct xusb *xusb, char *buf, int len, int timeout) +{ + int ret; + int retries = 0; + + dump_packet(LOG_DEBUG, DBG_MASK, __func__, buf, len); + if (EP_OUT(xusb) & USB_ENDPOINT_IN) { + ERR("%s called with an input endpoint 0x%x\n", + __func__, EP_OUT(xusb)); + return -EINVAL; + } +retry_write: + ret = usb_bulk_write(xusb->handle, EP_OUT(xusb), buf, len, timeout); + if (ret < 0) { + /* + * If the device was gone, it may be the + * result of renumeration. Ignore it. + */ + if (ret != -ENODEV) { + ERR("bulk_write to endpoint 0x%x failed: (%d) %s\n", + EP_OUT(xusb), ret, usb_strerror()); + dump_packet(LOG_ERR, DBG_MASK, "xusb_send[ERR]", + buf, len); + /*exit(2);*/ + } else { + DBG("bulk_write to endpoint 0x%x got ENODEV\n", + EP_OUT(xusb)); + xusb_close(xusb); + } + return ret; + } + if (!ret) { + ERR("bulk_write to endpoint 0x%x short write[%d]: (%d)\n", + EP_OUT(xusb), retries, ret); + if (retries++ > MAX_RETRIES) + return -EFAULT; + usleep(100); + goto retry_write; + } + if (ret != len) { + ERR("bulk_write to endpoint 0x%x short write: (%d) %s\n", + EP_OUT(xusb), ret, usb_strerror()); + dump_packet(LOG_ERR, DBG_MASK, "xusb_send[ERR]", buf, len); + return -EFAULT; + } + return ret; +} + +int xusb_recv(struct xusb *xusb, char *buf, size_t len, int timeout) +{ + int ret; + int retries = 0; + + if (EP_IN(xusb) & USB_ENDPOINT_OUT) { + ERR("%s called with an output endpoint 0x%x\n", + __func__, EP_IN(xusb)); + return -EINVAL; + } +retry_read: + ret = usb_bulk_read(xusb->handle, EP_IN(xusb), buf, len, timeout); + if (ret < 0) { + DBG("bulk_read from endpoint 0x%x failed: (%d) %s\n", + EP_IN(xusb), ret, usb_strerror()); + memset(buf, 0, len); + return ret; + } + if (!ret) { + ERR("bulk_read to endpoint 0x%x short read[%d]: (%d)\n", + EP_IN(xusb), retries, ret); + if (retries++ > MAX_RETRIES) + return -EFAULT; + usleep(100); + goto retry_read; + } + dump_packet(LOG_DEBUG, DBG_MASK, __func__, buf, ret); + return ret; +} + +int xusb_flushread(struct xusb *xusb) +{ + char tmpbuf[BUFSIZ]; + int ret; + + DBG("starting...\n"); + memset(tmpbuf, 0, BUFSIZ); + ret = xusb_recv(xusb, tmpbuf, BUFSIZ, 1); + if (ret < 0 && ret != -ETIMEDOUT) { + ERR("ret=%d\n", ret); + return ret; + } else if (ret > 0) { + DBG("Got %d bytes:\n", ret); + dump_packet(LOG_DEBUG, DBG_MASK, __func__, tmpbuf, ret); + } + return 0; +} + +/* + * Serialize calls to usb_find_busses()/usb_find_devices() + */ + +static const key_t SEM_KEY = 0x1a2b3c4d; +static int semid = -1; /* Failure */ + +static void xusb_lock_usb() +{ + struct sembuf sembuf; + + while (semid < 0) { + /* Maybe it was already created? */ + semid = semget(SEM_KEY, 1, 0); + if (semid < 0) { + /* No, let's create ourselves */ + semid = semget(SEM_KEY, 1, IPC_CREAT | IPC_EXCL | 0644); + if (semid < 0) { + /* Someone else won the race to create it */ + if (errno != ENOENT) + ERR("%s: semget() failed: %s\n", + __func__, strerror(errno)); + /* Retry */ + continue; + } + /* Initialize */ + if (semctl(semid, 0, SETVAL, 1) < 0) + ERR("%s: SETVAL() failed: %s\n", + __func__, strerror(errno)); + } + } + DBG("%d: LOCKING\n", getpid()); + sembuf.sem_num = 0; + sembuf.sem_op = -1; + sembuf.sem_flg = SEM_UNDO; + if (semop(semid, &sembuf, 1) < 0) + ERR("%s: semop() failed: %s\n", __func__, strerror(errno)); + DBG("%d: LOCKED\n", getpid()); +} + +static void xusb_unlock_usb() +{ + struct sembuf sembuf; + + DBG("%d: UNLOCKING\n", getpid()); + sembuf.sem_num = 0; + sembuf.sem_op = 1; + sembuf.sem_flg = SEM_UNDO; + if (semop(semid, &sembuf, 1) < 0) + ERR("%s: semop() failed: %s\n", __func__, strerror(errno)); + DBG("%d: UNLOCKED\n", getpid()); +} + +static int initizalized; + +static void xusb_init() +{ + if (!initizalized) { + xtalk_parse_options(); + if (!xtalk_option_no_lock()) + xusb_lock_usb(); + usb_init(); + usb_find_busses(); + usb_find_devices(); + initizalized = 1; + if (!xtalk_option_no_lock()) + xusb_unlock_usb(); + } +} + +/* XTALK option handling */ +static int use_clear_halt = 1; +static int libusb_no_lock = 0; + +static int xtalk_one_option(const char *option_string) +{ + if (strcmp(option_string, "use-clear-halt") == 0) { + use_clear_halt = 1; + return 0; + } + if (strcmp(option_string, "no-use-clear-halt") == 0) { + use_clear_halt = 0; + return 0; + } + if (strcmp(option_string, "no-lock") == 0) { + libusb_no_lock = 1; + return 0; + } + ERR("Unknown XTALK_OPTIONS content: '%s'\n", option_string); + return -EINVAL; +} + +int xtalk_option_use_clear_halt(void) +{ + return use_clear_halt; +} + +int xtalk_option_no_lock(void) +{ + return libusb_no_lock; +} + +int xtalk_parse_options(void) +{ + char *xtalk_options; + char *saveptr; + char *token; + int ret; + + xtalk_options = getenv("XTALK_OPTIONS"); + if (!xtalk_options) + return 0; + token = strtok_r(xtalk_options, " \t", &saveptr); + while (token) { + ret = xtalk_one_option(token); + if (ret < 0) + return ret; + token = strtok_r(NULL, " \t", &saveptr); + } + return 0; +} + diff --git a/xpp/xtalk/xusb.h b/xpp/xtalk/xusb.h new file mode 100644 index 0000000..01e1861 --- /dev/null +++ b/xpp/xtalk/xusb.h @@ -0,0 +1,102 @@ +#ifndef XUSB_H +#define XUSB_H +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* + * Xorcom usb handling + */ + +#define PACKET_SIZE 512 + +/* + * Specify the wanted interface + */ +struct xusb_spec { + /* Sanity checks so we know it is our device indeed */ + int num_interfaces; + int num_endpoints; + char *name; /* For debug/output purpose */ + /* What we will actually use */ + uint16_t my_vendor_id; + uint16_t my_product_id; + int my_interface_num; + int my_ep_out; + int my_ep_in; +}; + +void xusb_init_spec(struct xusb_spec *xusb_spec, char *name, + uint16_t vendor_id, uint16_t product_id, + int nifaces, int iface, int nep, int ep_out, int ep_in); + +struct xusb; + +/* + * Prototypes + */ +typedef int (*xusb_filter_t)(const struct xusb *xusb, void *data); +struct xlist_node *xusb_find_byproduct(const struct xusb_spec *specs, + int numspecs, xusb_filter_t filterfunc, void *data); +struct xusb *xusb_find_bypath(const struct xusb_spec *specs, int numspecs, + const char *path); +struct xusb *xusb_open_one(const struct xusb_spec *specs, int numspecs, + xusb_filter_t filterfunc, void *data); +struct xusb *xusb_find_iface(const char *devpath, int iface_num, + int ep_out, int ep_in, struct xusb_spec *dummy); + +/* + * A convenience filter + */ +int xusb_filter_bypath(const struct xusb *xusb, void *data); + +int xusb_interface(struct xusb *xusb); +int xusb_claim_interface(struct xusb *xusb); +void xusb_destroy(struct xusb *xusb); +int xusb_close(struct xusb *xusb); +size_t xusb_packet_size(const struct xusb *xusb); +void xusb_showinfo(const struct xusb *xusb); +const char *xusb_serial(const struct xusb *xusb); +const char *xusb_manufacturer(const struct xusb *xusb); +const char *xusb_product(const struct xusb *xusb); +uint16_t xusb_vendor_id(const struct xusb *xusb); +uint16_t xusb_product_id(const struct xusb *xusb); +const char *xusb_devpath(const struct xusb *xusb); +const struct xusb_spec *xusb_spec(const struct xusb *xusb); +int xusb_send(struct xusb *xusb, char *buf, int len, int timeout); +int xusb_recv(struct xusb *xusb, char *buf, size_t len, int timeout); +int xusb_flushread(struct xusb *xusb); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XUSB_H */ diff --git a/zonedata.c b/zonedata.c new file mode 100644 index 0000000..1d314b1 --- /dev/null +++ b/zonedata.c @@ -0,0 +1,1069 @@ +/* + * BSD Telephony Of Mexico "Tormenta" Tone Zone Support 2/22/01 + * + * Working with the "Tormenta ISA" Card + * + * Primary Author: Mark Spencer + * + * This information from ITU E.180 Supplement 2. + * UK information from BT SIN 350 Issue 1.1 + * Helpful reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU Lesser General Public License Version 2.1 as published + * by the Free Software Foundation. See the LICENSE.LGPL file + * included with this program for more details. + * + * In addition, when this program is distributed with Asterisk in + * any form that would qualify as a 'combined work' or as a + * 'derivative work' (but not mere aggregation), you can redistribute + * and/or modify the combination under the terms of the license + * provided with that copy of Asterisk, instead of the license + * terms granted here. + */ + +#include "tonezone.h" + +struct tone_zone builtin_zones[] = +{ + { .zone = 0, + .country = "us", + .description = "United States / North America", + .ringcadence = { 2000, 4000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "350+440" }, + { DAHDI_TONE_BUSY, "480+620/500,0/500" }, + { DAHDI_TONE_RINGTONE, "440+480/2000,0/4000" }, + { DAHDI_TONE_CONGESTION, "480+620/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "440/300,0/10000" }, + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, + { DAHDI_TONE_STUTTER, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 1, + .country = "au", + .description = "Australia", + .ringcadence = { 400, 200, 400, 2000 }, + .tones = { + + { DAHDI_TONE_DIALTONE, "415+440" }, + { DAHDI_TONE_BUSY, "425/375,0/375" }, + { DAHDI_TONE_RINGTONE, "413+438/400,0/200,413+438/400,0/2000" }, + /* The Australian congestion tone is 425Hz, 375ms On, 375ms Off, with the + * second cadence being half the amplitude of the first; so the first cadence + * is approximately -10dB with the second one being -20dB. Using the update + * ToneZone.c file, this can be accomplished by adding the "@" symbol in front + * of the frequency to reduce amplification, as in the following entry for + * Congestion: + */ + { DAHDI_TONE_CONGESTION, "425/375,0/375,425@/375,0/375" }, + { DAHDI_TONE_CALLWAIT, "425/100,0/200,425/200,0/4400" }, + { DAHDI_TONE_DIALRECALL, "413+428" }, + { DAHDI_TONE_RECORDTONE, "!425/1000,!0/15000,425/360,0/15000" }, + { DAHDI_TONE_INFO, "425/2500,0/500" }, + { DAHDI_TONE_STUTTER, "413+438/100,0/40" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 2, + .country = "fr", + .description = "France", + .ringcadence = { 1500, 3500 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + /* Dialtone can also be 440+330 */ + { DAHDI_TONE_DIALTONE, "440" }, + { DAHDI_TONE_BUSY, "440/500,0/500" }, + { DAHDI_TONE_RINGTONE, "440/1500,0/3500" }, + /* CONGESTION - not specified */ + { DAHDI_TONE_CONGESTION, "440/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "440/300,0/10000" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, + { DAHDI_TONE_STUTTER, "!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,440" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 3, + .country = "nl", + .description = "Netherlands", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + /* Most of these 425's can also be 450's */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "425/500,0/9500" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "950/330,1400/330,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "425/500,0/50" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 4, + .country = "uk", + .description = "United Kingdom", + .ringcadence = { 400, 200, 400, 2000 }, + .tones = { + /* From British Telecom SIN350 v1.2 */ + { DAHDI_TONE_DIALTONE, "350+440" }, + { DAHDI_TONE_BUSY, "400/375,0/375" }, + { DAHDI_TONE_RINGTONE, "400+450/400,0/200,400+450/400,0/2000" }, + { DAHDI_TONE_CONGESTION, "400/400,0/350,400/225,0/525" }, + { DAHDI_TONE_CALLWAIT, "400/100,0/4000" }, + { DAHDI_TONE_DIALRECALL, "350+440" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/60000" }, + { DAHDI_TONE_INFO, "950/330,0/15,1400/330,0/15,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "350+440/750,440/750" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 5, + .country = "fi", + .description = "Finland", + .ringcadence = { 1000, 4000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/300,0/300" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "425/150,0/150,425/150,0/8000" }, + { DAHDI_TONE_DIALRECALL, "425/650,0/25" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "950/650,0/325,950/325,0/30,1400/1300,0/2600" }, + { DAHDI_TONE_STUTTER, "425/650,0/25" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 6, + .country = "es", + .description = "Spain", + .ringcadence = { 1500, 3000}, + .tones = { + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/200,0/200" }, + { DAHDI_TONE_RINGTONE, "425/1500,0/3000" }, + { DAHDI_TONE_CONGESTION, "425/200,0/200,425/200,0/200,425/200,0/600" }, + { DAHDI_TONE_CALLWAIT, "425/175,0/175,425/175,0/3500" }, + { DAHDI_TONE_DIALRECALL, "!425/200,!0/200,!425/200,!0/200,!425/200,!0/200,425" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "950/330,0/1000" }, + { DAHDI_TONE_STUTTER, "425/500,0/50" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 7, + .country = "jp", + .description = "Japan", + .ringcadence = { 1000, 2000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "400" }, + { DAHDI_TONE_BUSY, "400/500,0/500" }, + { DAHDI_TONE_RINGTONE, "400+15/1000,0/2000" }, + { DAHDI_TONE_CONGESTION, "400/500,0/500" }, + { DAHDI_TONE_CALLWAIT, "400+16/500,0/8000" }, + { DAHDI_TONE_DIALRECALL, "!400/200,!0/200,!400/200,!0/200,!400/200,!0/200,400" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, + { DAHDI_TONE_STUTTER, "!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,400" }, + }, + .dtmf_high_level = -7, + .dtmf_low_level = -7, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 8, + .country = "no", + .description = "Norway", + .ringcadence = { 1000, 4000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "425/200,0/600,425/200,0/10000" }, + { DAHDI_TONE_DIALRECALL, "470/400,425/400" }, + { DAHDI_TONE_RECORDTONE, "1400/400,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0" }, + { DAHDI_TONE_STUTTER, "470/400,425/400" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 9, + .country = "at", + .description = "Austria", + .ringcadence = { 1000, 5000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "420" }, + { DAHDI_TONE_BUSY, "420/400,0/400" }, + { DAHDI_TONE_RINGTONE, "420/1000,0/5000" }, + { DAHDI_TONE_CONGESTION, "420/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "420/40,0/1960" }, + { DAHDI_TONE_DIALRECALL, "420" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/80,0/14920" }, + { DAHDI_TONE_INFO, "950/330,1450/330,1850/330,0/1000" }, + { DAHDI_TONE_STUTTER, "380+420" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 10, + .country = "nz", + .description = "New Zealand", + .ringcadence = { 400, 200, 400, 2000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "400" }, + { DAHDI_TONE_BUSY, "400/500,0/500" }, + { DAHDI_TONE_RINGTONE, "400+450/400,0/200,400+450/400,0/2000" }, + { DAHDI_TONE_CONGESTION, "400/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "400/250,0/250,400/250,0/3250" }, + { DAHDI_TONE_DIALRECALL, "!400/100!0/100,!400/100,!0/100,!400/100,!0/100,400" }, + { DAHDI_TONE_RECORDTONE, "1400/425,0/15000" }, + { DAHDI_TONE_INFO, "400/750,0/100,400/750,0/100,400/750,0/100,400/750,0/400" }, + { DAHDI_TONE_STUTTER, "!400/100!0/100,!400/100,!0/100,!400/100,!0/100,!400/100!0/100,!400/100,!0/100,!400/100,!0/100,400" }, + }, + .dtmf_high_level = -11, + .dtmf_low_level = -9, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 11, + .country = "it", + .description = "Italy", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425/200,0/200,425/600,0/1000" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "425/400,0/100,425/250,0/100,425/150,0/14000" }, + { DAHDI_TONE_DIALRECALL, "470/400,425/400" }, + { DAHDI_TONE_RECORDTONE, "1400/400,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0" }, + { DAHDI_TONE_STUTTER, "470/400,425/400" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 12, + .country = "us-old", + .description = "United States Circa 1950 / North America", + .ringcadence = { 2000, 4000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "600*120" }, + { DAHDI_TONE_BUSY, "500*100/500,0/500" }, + { DAHDI_TONE_RINGTONE, "420*40/2000,0/4000" }, + { DAHDI_TONE_CONGESTION, "500*100/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "440/300,0/10000" }, + { DAHDI_TONE_DIALRECALL, "!600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,600*120" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, + { DAHDI_TONE_STUTTER, "!600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,600*120" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 13, + .country = "gr", + .description = "Greece", + .ringcadence = { 1000, 4000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "425/200,0/300,425/700,0/800" }, + { DAHDI_TONE_BUSY, "425/300,0/300" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "425/150,0/150,425/150,0/8000" }, + { DAHDI_TONE_DIALRECALL, "425/650,0/25" }, + { DAHDI_TONE_RECORDTONE, "1400/400,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0" }, + { DAHDI_TONE_STUTTER, "425/650,0/25" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 14, + .country = "tw", + .description = "Taiwan", + .ringcadence = { 1000, 4000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "350+440" }, + { DAHDI_TONE_BUSY, "480+620/500,0/500" }, + { DAHDI_TONE_RINGTONE, "440+480/1000,0/2000" }, + { DAHDI_TONE_CONGESTION, "480+620/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "350+440/250,0/250,350+440/250,0/3250" }, + { DAHDI_TONE_DIALRECALL, "300/1500,0/500" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, + { DAHDI_TONE_STUTTER, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + }, + .dtmf_high_level = -11, + .dtmf_low_level = -9, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 15, + .country = "cl", + .description = "Chile", + .ringcadence = { 1000, 3000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "400" }, + { DAHDI_TONE_BUSY, "400/500,0/500" }, + { DAHDI_TONE_RINGTONE, "400/1000,0/3000" }, + { DAHDI_TONE_CONGESTION, "400/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "400/250,0/8750" }, + { DAHDI_TONE_DIALRECALL, "!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,400" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/333,!1400/333,!1800/333,0" }, + { DAHDI_TONE_STUTTER, "!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,400" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 16, + .country = "se", + .description = "Sweden", + .ringcadence = { 1000, 5000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/250,0/250" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/5000" }, + { DAHDI_TONE_CONGESTION, "425/250,0/750" }, + { DAHDI_TONE_CALLWAIT, "425/200,0/500,425/200,0/9100" }, + { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/332,!0/24,!1400/332,!0/24,!1800/332,!0/2024," + "!950/332,!0/24,!1400/332,!0/24,!1800/332,!0/2024," + "!950/332,!0/24,!1400/332,!0/24,!1800/332,!0/2024," + "!950/332,!0/24,!1400/332,!0/24,!1800/332,!0/2024," + "!950/332,!0/24,!1400/332,!0/24,!1800/332,0" }, + /*{ DAHDI_TONE_STUTTER, "425/320,0/20" }, Real swedish standard, not used for now */ + { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 17, + .country = "be", + .description = "Belgium", + .ringcadence = { 1000, 3000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/3000" }, + { DAHDI_TONE_CONGESTION, "425/167,0/167" }, + { DAHDI_TONE_CALLWAIT, "1400/175,0/175,1400/175,0/3500" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "900/330,1400/330,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "425/1000,0/250" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 18, + .country = "sg", + .description = "Singapore", + .ringcadence = { 400, 200, 400, 2000 }, + .tones = { + /* Reference: http://www.ida.gov.sg/idaweb/doc/download/I397/ida_ts_pstn1_i4r2.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/750,0/750" }, + { DAHDI_TONE_RINGTONE, "425*24/400,0/200,425*24/400,0/2000" }, + { DAHDI_TONE_CONGESTION, "425/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "425*24/300,0/200,425*24/300,0/3200" }, + /* DIALRECALL - not specified - use repeating Holding Tone A,B*/ + { DAHDI_TONE_DIALRECALL, "425*24/500,0/500,425/500,0/2500" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "950/330,1400/330,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "!425/200,!0/200,!425/600,!0/200,!425/200,!0/200,!425/600,!0/200,!425/200,!0/200,!425/600,!0/200,!425/200,!0/200,!425/600,!0/200,425" }, + }, + .dtmf_high_level = -11, + .dtmf_low_level = -9, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 19, + .country = "il", + .description = "Israel", + .ringcadence = { 1000, 3000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "414" }, + { DAHDI_TONE_BUSY, "414/500,0/500" }, + { DAHDI_TONE_RINGTONE, "414/1000,0/3000" }, + { DAHDI_TONE_CONGESTION, "414/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "414/100,0/100,414/100,0/100,414/600,0/3000" }, + { DAHDI_TONE_DIALRECALL, "!414/100,!0/100,!414/100,!0/100,!414/100,!0/100,414" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "1000/330,1400/330,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,414" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 20, + .country = "br", + .description = "Brazil", + .ringcadence = { 1000, 4000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/250,0/250" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/250,0/250,425/750,0/250" }, + { DAHDI_TONE_CALLWAIT, "425/50,0/1000" }, + { DAHDI_TONE_DIALRECALL, "350+440" }, + { DAHDI_TONE_RECORDTONE, "425/250,0/250" }, + { DAHDI_TONE_INFO, "950/330,1400/330,1800/330" }, + { DAHDI_TONE_STUTTER, "350+440" } }, + .dtmf_high_level = -10, + .dtmf_low_level = -12, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 21, + .country = "hu", + .description = "Hungary", + .ringcadence = { 1250, 3750 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/300,0/300" }, + { DAHDI_TONE_RINGTONE, "425/1250,0/3750" }, + { DAHDI_TONE_CONGESTION, "425/300,0/300" }, + { DAHDI_TONE_CALLWAIT, "425/40,0/1960" }, + { DAHDI_TONE_DIALRECALL, "425+450" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/400,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0" }, + { DAHDI_TONE_STUTTER, "350+375+400" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 22, + .country = "lt", + .description = "Lithuania", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/350,0/350" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "425/150,0/150,425/150,0/4000" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0" }, + /* STUTTER not specified */ + { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 23, + .country = "pl", + .description = "Poland", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/500,0/500" }, + { DAHDI_TONE_CALLWAIT, "425/150,0/150,425/150,0/4000" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,0" }, + /* STUTTER not specified */ + { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 24, + .country = "za", + .description = "South Africa", + .ringcadence = { 400, 200, 400, 2000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "400*33" }, + { DAHDI_TONE_BUSY, "400/500,0/500" }, + { DAHDI_TONE_RINGTONE, "400*33/400,0/200,400*33/400,0/2000" }, + { DAHDI_TONE_CONGESTION, "400/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "400*33/250,0/250,400*33/250,0/250,400*33/250,0/250,400*33/250,0/250" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "350+440" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0" }, + /* STUTTER not specified */ + { DAHDI_TONE_STUTTER, "!400*33/100,!0/100,!400*33/100,!0/100,!400*33/100,!0/100,!400*33/100,!0/100,!400*33/100,!0/100,!400*33/100,!0/100,400*33" }, + }, + .dtmf_high_level = -11, + .dtmf_low_level = -13, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 25, + .country = "pt", + .description = "Portugal", + .ringcadence = { 1000, 5000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/5000" }, + { DAHDI_TONE_CONGESTION, "425/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "425/200,425/200,425/200,0/5000" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "425/1000,0/200" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "950/330,1400/330,1800/330,0/1000" }, + /* STUTTER not specified */ + { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 26, + .country = "ee", + .description = "Estonia", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/300,0/300" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "950/650,0/325,950/325,0/30,1400/1300,0/2600" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "425/650,0/25" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "950/0,0/325,950/325,0/30,1400/1300,0/2600" }, + /* STUTTER not specified */ + { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 27, + .country = "mx", + .description = "Mexico", + .ringcadence = { 2000, 4000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/250,0/250" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "425/200,0/600,425/200,0/10000" }, + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "950/330,0/30,1400/330,0/30,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + }, + .dtmf_high_level = -8, + .dtmf_low_level = -6, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 28, + .country = "in", + .description = "India", + .ringcadence = { 400, 200, 400, 2000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "400*25" }, + { DAHDI_TONE_BUSY, "400/750,0/750" }, + { DAHDI_TONE_RINGTONE, "400*25/400,0/200,400*25/400,0/2000" }, + { DAHDI_TONE_CONGESTION, "400/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "400/200,0/100,400/200,0/7500" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + /* INFO - not specified */ + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0/1000" }, + /* STUTTER - not specified */ + { DAHDI_TONE_STUTTER, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 29, + .country = "de", + .description = "Germany", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/480,0/480" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/240,0/240" }, + { DAHDI_TONE_CALLWAIT, "!425/200,!0/200,!425/200,!0/5000,!425/200,!0/200,!425/200,!0/5000,!425/200,!0/200,!425/200,!0/5000,!425/200,!0/200,!425/200,!0/5000,!425/200,!0/200,!425/200,0" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/80,0/15000" }, + { DAHDI_TONE_INFO, "950/330,1400/330,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "425+400" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 30, + .country = "ch", + .description = "Switzerland", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "425/200,0/200,425/200,0/4000" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/80,0/15000" }, + { DAHDI_TONE_INFO, "950/330,1400/330,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "425+340/1100,0/1100" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 31, + .country = "dk", + .description = "Denmark", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "!425/200,!0/600,!425/200,!0/3000,!425/200,!0/200,!425/200,0" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/80,0/15000" }, + { DAHDI_TONE_INFO, "950/330,1400/330,1800/330,0/1000" }, + /* STUTTER - not specified */ + { DAHDI_TONE_STUTTER, "425/450,0/50" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 32, + .country = "cz", + .description = "Czech Republic", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425/330,0/330,425/660,0/660" }, + { DAHDI_TONE_BUSY, "425/330,0/330" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/165,0/165" }, + { DAHDI_TONE_CALLWAIT, "425/330,0/9000" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425/330,0/330,425/660,0/660" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/14000" }, + { DAHDI_TONE_INFO, "950/330,0/30,1400/330,0/30,1800/330,0/1000" }, + /* STUTTER - not specified */ + { DAHDI_TONE_STUTTER, "425/450,0/50" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 33, + .country = "cn", + .description = "China", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "450" }, + { DAHDI_TONE_BUSY, "450/350,0/350" }, + { DAHDI_TONE_RINGTONE, "450/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "450/700,0/700" }, + { DAHDI_TONE_CALLWAIT, "450/400,0/4000" }, + { DAHDI_TONE_DIALRECALL, "450" }, + { DAHDI_TONE_RECORDTONE, "950/400,0/10000" }, + { DAHDI_TONE_INFO, "450/100,0/100,450/100,0/100,450/100,0/100,450/400,0/400" }, + /* STUTTER - not specified */ + { DAHDI_TONE_STUTTER, "450+425" }, + }, + .dtmf_high_level = -11, + .dtmf_low_level = -9, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 34, + .country = "ar", + .description = "Argentina", + .ringcadence = { 1000, 4500 }, + .tones = { + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/300,0/300" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4500" }, + { DAHDI_TONE_CONGESTION, "425/200,0/300" }, + { DAHDI_TONE_CALLWAIT, "425/200,0/9000" }, + { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425/330,0/330,425/660,0/660" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/14000" }, + { DAHDI_TONE_INFO, "425/100,0/100" }, + { DAHDI_TONE_STUTTER, "425/450,0/50" }, + }, + .dtmf_high_level = -11, + .dtmf_low_level = -9, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 35, + .country = "my", + .description = "Malaysia", + .ringcadence = { 400, 200, 400, 2000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/400,0/200,425/400,0/2000" }, + { DAHDI_TONE_CONGESTION, "425/500,0/500" }, + { DAHDI_TONE_CALLWAIT, "425/100,0/4000" }, + { DAHDI_TONE_DIALRECALL, "350+440" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/60000" }, + { DAHDI_TONE_INFO, "950/330,0/15,1400/330,0/15,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "450+425" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 36, + .country = "th", + .description = "Thailand", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "400*50" }, + { DAHDI_TONE_BUSY, "400/500,0/500" }, + { DAHDI_TONE_RINGTONE, "400/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "400/300,0/300" }, + { DAHDI_TONE_CALLWAIT, "1000/400,10000/400,1000/400" }, + /* DIALRECALL - not specified - use special dial tone instead. */ + { DAHDI_TONE_DIALRECALL, "400*50/400,0/100,400*50/400,0/100" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + /* INFO - specified as an announcement - use tones instead. */ + { DAHDI_TONE_INFO, "950/330,1400/330,1800/330" }, + /* STUTTER - not specified */ + { DAHDI_TONE_STUTTER, "!400/200,!0/200,!400/600,!0/200,!400/200,!0/200,!400/600,!0/200,!400/200,!0/200,!400/600,!0/200,!400/200,!0/200,!400/600,!0/200,400" }, + }, + .dtmf_high_level = -11, + .dtmf_low_level = -9, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 37, + .country = "bg", + .description = "Bulgaria", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "425/150,0/150,425/150,0/4000" }, + { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + { DAHDI_TONE_RECORDTONE, "1400/425,0/15000" }, + { DAHDI_TONE_INFO, "950/330,1400/330,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "425/1500,0/100" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 38, + .country = "ve", + .description = "Venezuela", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "400+450/300,0/6000" }, + { DAHDI_TONE_DIALRECALL, "425" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1440/330,!1800/330,0/1000" }, + /* STUTTER - not specified */ + { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + }, + .dtmf_high_level = -7, + .dtmf_low_level = -9, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 39, + .country = "ph", + .description = "Philippines", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "480+620/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425+480/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "480+620/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "440/300,0/10000" }, + /* DIAL RECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + /* RECORD TONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + /* INFO TONE - not specified */ + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, + /* STUTTER TONE - not specified */ + { DAHDI_TONE_STUTTER, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 40, + .country = "ru", + .description = "Russian Federation", + .ringcadence = { 1000, 4000 }, + .tones = { + /* References: + http://www.minsvyaz.ru/site.shtml?id=1806 + http://www.aboutphone.info/lib/gost/45-223-2001.html */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/350,0/350" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/175,0/175" }, + { DAHDI_TONE_CALLWAIT, "425/200,0/5000" }, + { DAHDI_TONE_RECORDTONE, "1400/400,0/15000" }, + { DAHDI_TONE_INFO, "950/330,1440/330,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { + .zone = 41, + .country = "tr", + .description = "Turkey", + .ringcadence = { 2000, 4000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "450" }, + { DAHDI_TONE_BUSY, "450/500,0/500" }, + { DAHDI_TONE_RINGTONE, "450/2000,0/4000" }, + { DAHDI_TONE_CONGESTION, "!450/200,!0/200,!450/200,!0/200,!450/200,!0/200,450/600,0/200" }, + { DAHDI_TONE_CALLWAIT, "450/200,0/600,450/200,0/800" }, + /* This should actually be 950+1400+1800, but we only support 2 tones at a time */ + { DAHDI_TONE_INFO, "!950+1400/300,!0/1000,!950+1400/300,!0/1000,!950+1400/1000,0" }, + { DAHDI_TONE_STUTTER, "!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,450" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { + .zone = 42, + .country = "pa", + .description = "Panama", + .ringcadence = { 2000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/320,0/320" }, + { DAHDI_TONE_RINGTONE, "425/1200,0/4650" }, + { DAHDI_TONE_CONGESTION, "425/320,0/320" }, + { DAHDI_TONE_CALLWAIT, "425/180,0/180,425/180" }, + /* RECALL DIAL TONE - not specified */ + { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + /* RECORD TONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, + /* STUTTER TONE - not specified */ + { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { + .zone = 43, + .country = "mo", + .description = "Macao,China", + .ringcadence = { 1000, 4000 }, + .tones = { + /* References: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "425/200,0/600" }, + /* RECORD TONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/400,0/15000" }, + { DAHDI_TONE_INFO, "950/333,1400/333,1800/333,0/1000" }, + /* STUTTER TONE - not specified */ + { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { + .zone = 44, + .country = "cr", + .description = "Costa Rica", + .ringcadence = { 1203, 4797 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf [^] */ + { DAHDI_TONE_DIALTONE, "450" }, + { DAHDI_TONE_BUSY, "450/330,0/330" }, + { DAHDI_TONE_RINGTONE, "450/1203,0/4900" }, + { DAHDI_TONE_CONGESTION, "450/330,0/330" }, + { DAHDI_TONE_CALLWAIT, "450/150,0/150,450/150,450/8000" }, + /* RECALL DIAL TONE - not specified */ + { DAHDI_TONE_DIALRECALL, "!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,450" }, + /* RECORD TONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, + /* STUTTER TONE - not specified */ + { DAHDI_TONE_STUTTER, "!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,450" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { + .zone = 45, + .country = "ae", + .description = "United Arab Emirates", + .ringcadence = { 1500, 4000 }, + .tones = { + /* References: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "350+440" }, + { DAHDI_TONE_BUSY, "400/375,0/375" }, + { DAHDI_TONE_RINGTONE, "400+425/400,0/200,400+425/400,0/2000" }, + { DAHDI_TONE_CONGESTION, "425/400,0/350,425/225,0/525" }, + { DAHDI_TONE_CALLWAIT, "420/40,0/1960" }, + /* RECORD TONE */ + { DAHDI_TONE_RECORDTONE, "1400/80,0/14920" }, + { DAHDI_TONE_INFO, "950/330,1450/330,1850/330,0/1000" }, + /* STUTTER TONE */ + { DAHDI_TONE_STUTTER, "380+420" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = -1 } +};